"""Tests for rebreak methods.

Specifically:
- ReflowSequence.rebreak()
"""

import logging

import pytest

from sqlfluff.core import Linter
from sqlfluff.utils.reflow.sequence import ReflowSequence

def parse_ansi_string(sql, config):
    """Parse an ansi sql string for testing."""
    linter = Linter(config=config)
    return linter.parse_string(sql).tree

@pytest.mark.parametrize(
    "raw_sql_in,raw_sql_out",
    [
        # Trivial Case
        ("select 1", "select 1"),
        # These rely on the default config being for leading operators
        ("select 1\n+2", "select 1\n+2"),
        ("select 1+\n2", "select 1\n+ 2"),  # NOTE: Implicit respace.
        ("select\n  1 +\n  2", "select\n  1\n  + 2"),
        ("select\n  1 +\n  -- comment\n  2", "select\n  1\n  -- comment\n  + 2"),
        # These rely on the default config being for trailing commas
        ("select a,b", "select a,b"),
        ("select a\n,b", "select a,\nb"),
        ("select\n  a\n  , b", "select\n  a,\n  b"),
        ("select\n    a\n    , b", "select\n    a,\n    b"),
        ("select\n  a\n    , b", "select\n  a,\n    b"),
        ("select\n  a\n  -- comment\n  , b", "select\n  a,\n  -- comment\n  b"),
    ],
)
def test_reflow__sequence_rebreak_root(raw_sql_in, raw_sql_out, default_config, caplog):
    """Test the ReflowSequence.rebreak() method directly.

    Focused around a whole segment.
    """
    root = parse_ansi_string(raw_sql_in, default_config)
    print(root.stringify())
    seq = ReflowSequence.from_root(root, config=default_config)
    for idx, elem in enumerate(seq.elements):
        print(idx, elem)

    with caplog.at_level(logging.DEBUG, logger="sqlfluff.rules.reflow"):
        new_seq = seq.rebreak()

    print(new_seq.get_fixes())
    assert new_seq.get_raw() == raw_sql_out

@pytest.mark.parametrize(
    "raw_sql_in,target_idx,seq_sql_in,seq_sql_out",
    [
        ("select 1+\n(2+3)", 4, "1+\n(", "1\n+ ("),
        ("select a,\n(b+c)", 4, "a,\n(", "a,\n("),
        ("select a\n  , (b+c)", 6, "a\n  , (", "a,\n  ("),
        # Here we don't have enough context to rebreak it so
        # it should be left unaltered.
        ("select a,\n(b+c)", 6, ",\n(b", ",\n(b"),
        # This intentionally targets an incomplete span.
        ("select a<=b", 4, "a<=", "a<="),
    ],
)
def test_reflow__sequence_rebreak_target(
    raw_sql_in, target_idx, seq_sql_in, seq_sql_out, default_config, caplog
):
    """Test the ReflowSequence.rebreak() method directly.

    Focused around a target segment. This intentionally
    stretches some of the span logic.
    """
    root = parse_ansi_string(raw_sql_in, default_config)
    print(root.stringify())
    target = root.raw_segments[target_idx]
    print("Target: ", target)
    seq = ReflowSequence.from_around_target(target, root, config=default_config)
    for idx, elem in enumerate(seq.elements):
        print(idx, elem)
    assert seq.get_raw() == seq_sql_in

    with caplog.at_level(logging.DEBUG, logger="sqlfluff.rules.reflow"):
        new_seq = seq.rebreak()

    print(new_seq.get_fixes())
    assert new_seq.get_raw() == seq_sql_out


#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   1614. 括号的最大嵌套深度.py
@Contact :   muyisanshuiliang@hotmail.com

@Modify Time      @Author               @Version
------------      -------               --------
2021/3/11 9:45   muyisanshuiliang      3.9
@Description:
---------------------------------------------------------------
如果字符串满足以下条件之一，则可以称之为 有效括号字符串（valid parentheses string，可以简写为 VPS）：

字符串是一个空字符串 ""，或者是一个不为 "(" 或 ")" 的单字符。
字符串可以写为 AB（A 与 B 字符串连接），其中 A 和 B 都是 有效括号字符串 。
字符串可以写为 (A)，其中 A 是一个 有效括号字符串 。
类似地，可以定义任何有效括号字符串 S 的 嵌套深度 depth(S)：

depth("") = 0
depth(C) = 0，其中 C 是单个字符的字符串，且该字符不是 "(" 或者 ")"
depth(A + B) = max(depth(A), depth(B))，其中 A 和 B 都是 有效括号字符串
depth("(" + A + ")") = 1 + depth(A)，其中 A 是一个 有效括号字符串
例如：""、"()()"、"()(()())" 都是 有效括号字符串（嵌套深度分别为 0、1、2），而 ")(" 、"(()" 都不是 有效括号字符串 。
给你一个 有效括号字符串 s，返回该字符串的 s 嵌套深度 。

示例 1：
输入：s = "(1+(2*3)+((8)/4))+1"
输出：3
解释：数字 8 在嵌套的 3 层括号中。

示例 2：
输入：s = "(1)+((2))+(((3)))"
输出：3

示例 3：
输入：s = "1+(2*3)/(2-1)"
输出：1

示例 4：
输入：s = "1"
输出：0

提示：
1 <= s.length <= 100
s 由数字 0-9 和字符 '+'、'-'、'*'、'/'、'('、')' 组成
题目数据保证括号表达式 s 是 有效的括号表达式
'''

# import lib
class Solution:
    def maxDepth(self, s: str) -> int:
        deep, ans = 0, 0
        # 当出现左括号的时候，当前嵌套深度+1，当出现右括号的时候当前嵌套深度-1，作为下一次嵌套的基数
        for item in s:
            if item == '(':
                deep += 1
            elif item == ')':
                # 当出现右括号的时候，最大值为当前嵌套深度与结果之间取最大值，
                ans = max(deep, ans)
                # 对嵌套深度进行-1，作为下一次嵌套的基数
                deep -= 1
        return ans

solution = Solution()
print(solution.maxDepth("(1)+((2))+(((3)))"))
print(solution.maxDepth("()(()())"))

1614. 括号的最大嵌套深度.py


import threading
import socket
# Connection Data
host = '51'  # lcalhost
port = 22
address = (host, port)

# Starting Server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((address))
server.listen()
# Lists For Clients and Their Nicknames
clients = []
nicknames = []

# Sending Messages To All Connected Clients
def broadcast(message):
    for client in clients:
        client.send(message)

# Handling Messages From Clients

def handle(client):
    while True:
        try:
            # Broadcasting Messages
            message = client.recv(1024)
            broadcast(message)
        except:
            # Removing And Closing Clients
            index = clients.index(client)
            clients.remove(client)
            client.close()
            nickname = nicknames[index]
            broadcast('{} left!'.format(nickname).encode('ascii'))
            nicknames.remove(nickname)
            break

# Receiving / Listening Function

def receive():
    while True:
        # Accept Connection
        client, address = server.accept()
        print("Connected with {}".format(str(address)))

        # Request And Store Nickname
        client.send('NICK'.encode('ascii'))
        nickname = client.recv(1024).decode('ascii')
        nicknames.append(nickname)
        clients.append(client)

        # Print And Broadcast Nickname
        print("Nickname is {}".format(nickname))
        broadcast("{} joined!".format(nickname).encode('ascii'))
        client.send('Connected to server!'.encode('ascii'))

        # Start Handling Thread For Client
        thread = threading.Thread(target=handle, args=(client,))
        thread.start()

receive()

# blocking

def blocking_modes():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setblocking(1)
    s.settimeout(0.5)
    s.bind(("00000", 0))

    socket_address = s.getsockname()
    print("Trivial Server launched on socket: %s" % str(socket_address))
    while(1):
        s.listen(1)

if __name__ == '__main__':
    if nickname == nickname in clients:
        nickname.client.edit_permissions(chat, user, view_messages=False)

# link:"https://youtu.be/3UOyky9sEQY"

# python server.py


import importlib
import os
import pathlib
import random
import sys
import pandas as pd
import numpy as np
from functools import partial
from joblib import func_inspect as jfi

from ..logging import logger

__all__ = [
    'deserialize_partial',
    'normalize_labels',
    'partial_call_signature',
    'read_space_delimited',
    'reservoir_sample',
    'serialize_partial',
]

_MODULE = sys.modules[__name__]
_MODULE_DIR = pathlib.Path(os.path.dirname(os.path.abspath(__file__)))

def read_space_delimited(filename, skiprows=None, class_labels=True, metadata=None):
    """Read an space-delimited file

    Data is space-delimited. Last column is the (string) label for the data

    Note: we can't use automatic comment detection, as `#` characters are also
    used as data labels.

    Parameters
    ----------
    skiprows: list-like, int or callable, optional
        list of rows to skip when reading the file. See `pandas.read_csv`
        entry on `skiprows` for more
    class_labels: boolean
        if true, the last column is treated as the class (target) label
    """
    with open(filename, 'r') as fd:
        df = pd.read_csv(fd, skiprows=skiprows, skip_blank_lines=True,
                           comment=None, header=None, sep=' ', dtype=str)
        # targets are last column. Data is everything else
        if class_labels is True:
            target = df.loc[:, df.columns[-1]].values
            data = df.loc[:, df.columns[:-1]].values
        else:
            data = df.values
            target = np.zeros(data.shape[0])
        return data, target, metadata

def normalize_labels(target):
    """Map an arbitary target vector to an integer vector

    Returns
    -------
    tuple: (mapped_target, label_map)

    where:
        mapped_target: integer vector of same shape as target
        label_map: dict mapping mapped_target integers to original labels

    Examples
    --------
    >>> target = np.array(['a','b','c','a'])
    >>> mapped_target, label_map = normalize_labels(target)
    >>> mapped_target
    array([0, 1, 2, 0])

    The following should always be true

    >>> all(np.vectorize(label_map.get)(mapped_target) == target)
    True
    """
    label_map = {k:v for k, v in enumerate(np.unique(target))}
    label_map_inv = {v:k for k, v in label_map.items()}
    mapped_target = np.vectorize(label_map_inv.get)(target)

    return mapped_target, label_map

def partial_call_signature(func):
    """Return the fully qualified call signature for a (partial) function
    """
    func = partial(func)
    fa = jfi.getfullargspec(func)
    default_kw = {}
    if fa.args:
        default_kw = dict(zip(fa.args, fa.defaults))
    if getattr(fa, 'kwonlydefaults', None):
        fq_keywords = {**default_kw, **fa.kwonlydefaults}
    else:
        fq_keywords = default_kw
    return jfi.format_signature(func.func, *func.args, **fq_keywords)

def process_dataset_default(metadata=None, **kwargs):
    """Placeholder for data processing function"""
    dataset_name = kwargs.get('dataset_name', 'unknown-dataset')
    logger.warning(f"Default {dataset_name}: Add parse function to generate `data` or `target`")
    return None, None, metadata

def deserialize_partial(func_dict, delete_keys=False,
                        output_key_base='load_function'):
    """Convert a serialized function call into a partial

    if there is an error, returns a default function (process_dataset_default)

    Parameters
    ----------
    func_dict: dict containing
        {output_key_base}_name: function name
        {output_key_base}_module: module containing function
        {output_key_base}_args: args to pass to function
        {output_key_base}_kwargs: kwargs to pass to function
    """

    if delete_keys:
        args = func_dict.pop(f"{output_key_base}_args", [])
        kwargs = func_dict.pop(f"{output_key_base}_kwargs", {})
        base_name = func_dict.pop(f"{output_key_base}_name", 'process_dataset_default')
        func_mod_name = func_dict.pop(f'{output_key_base}_module', None)
    else:
        args = func_dict.get(f"{output_key_base}_args", [])
        kwargs = func_dict.get(f"{output_key_base}_kwargs", {})
        base_name = func_dict.get(f"{output_key_base}_name", 'process_dataset_default')
        func_mod_name = func_dict.get(f'{output_key_base}_module', None)

    fail_func = partial(process_dataset_default, dataset_name=base_name)

    try:
        if func_mod_name:
            func_mod = importlib.import_module(func_mod_name)
        else:
            func_mod = _MODULE
        func_name = getattr(func_mod, base_name, fail_func)
    except ModuleNotFoundError as e:
        logger.error(f"Invalid parse_function: {e}")
        func_name = fail_func
    func = partial(func_name, *args, **kwargs)

    return func

def serialize_partial(func_name, output_key_base='load_function'):
    """Serialize a function call to a dictionary.

    Parameters
    ----------
    func_name: partial function.
    output_key_base

    Returns
    -------
    dict containing:
        {output_key_base}_name: function name
        {output_key_base}_module: fully-qualified module name containing function
        {output_key_base}_args: args to pass to function
        {output_key_base}_kwargs: kwargs to pass to function
    """

    entry = {}
    if func_name is None:
        logger.warning(f"serialize_partial: `{output_key_base}` is None. Ignoring.")
        return entry
    func = partial(func_name)
    entry[f'{output_key_base}_module'] = ".".join(jfi.get_func_name(func.func)[0])
    entry[f'{output_key_base}_name'] = jfi.get_func_name(func.func)[1]
    entry[f'{output_key_base}_args'] = func.args
    entry[f'{output_key_base}_kwargs'] = func.keywords
    return entry

def reservoir_sample(filename, n_samples=1, random_seed=None):
    """Return a random subset of lines from a file

    Parameters
    ----------
    filename: path
        File to be loaded
    n_samples: int
        number of lines to return
    random_seed: int or None
        If set, use this as the random seed
    """
    if random_seed is not None:
        random.seed(random_seed)
    sample = []
    with open(filename) as f:
        for n, line in enumerate(f):
            if n < n_samples:
                sample.append(line.rstrip())
            else:
                r = random.randint(0, n_samples)
                if r < n_samples:
                    sample[r] = line.rstrip()
    return sample


""" Search page route. """

import time

from flask import render_template
from flask import current_app as app
from flask import request

from hubgrep.constants import PARAM_OFFSET, PARAM_PER_PAGE, FORM_ARGS
from hubgrep.lib.pagination import get_page_links
from hubgrep.lib.manticore import ManticoreSearch, SearchMeta
from hubgrep.lib.manticore import UserError
from hubgrep.lib.search_form import SearchForm
from hubgrep.frontend_blueprint import frontend

import logging

logger = logging.getLogger(__name__)

@frontend.route("/")
def search():
    total_time = time.time()
    results_offset = int(request.args.get(PARAM_OFFSET, 0))
    results_per_page = int(
        request.args.get(PARAM_PER_PAGE, app.config["PAGINATION_PER_PAGE_DEFAULT"])
    )
    form = SearchForm(
        search_phrase=request.args.get(FORM_ARGS.search_phrase, ""),
        exclude_service_checkboxes=SearchForm.get_request_service_checkboxes(),
        exclude_forks=request.args.get(FORM_ARGS.exclude_forks, "") == "on",
        exclude_archived=request.args.get(FORM_ARGS.exclude_archived, "") == "on",
        exclude_mirror=request.args.get(FORM_ARGS.exclude_mirror, "") == "on",
        exclude_empty=request.args.get(FORM_ARGS.exclude_empty, "") == "on",
        created_after=request.args.get(FORM_ARGS.created_after, ""),
        created_before=request.args.get(FORM_ARGS.created_before, ""),
        updated_after=request.args.get(FORM_ARGS.updated_after, ""),
        pushed_after=request.args.get(FORM_ARGS.pushed_after, ""),
    )
    results_page = []
    user_errors = []
    pagination_links = []
    meta = SearchMeta([])
    if form.search_phrase:
        try:
            results_page, meta = ManticoreSearch.search(
                form.search_phrase,
                results_offset=results_offset,
                results_per_page=results_per_page,
                exclude_hosting_service_ids=form.get_excluded_hosting_service_ids(),
                exclude_forks=form.exclude_forks,
                exclude_archived=form.exclude_archived,
                exclude_mirror=form.exclude_mirror,
                exclude_empty=form.exclude_empty,
                created_after=form.created_after_dt,
                created_before=form.created_before_dt,
                updated_after=form.updated_after_dt,
                pushed_after=form.pushed_after_dt,
            )
        except UserError as e:
            user_errors.append(e)

        if meta.warning:
            user_errors.append(meta.warning)

        pagination_links = get_page_links(request.full_path, results_offset, results_per_page, meta.total)

    template_path = (
        "search/search_list.html" if form.search_phrase else "search/landing_page.html"
    )
    # obviously we are missing the time it takes to render and respond
    # - but we measure our own "total" to give a more realistic time
    total_time = time.time() - total_time
    logger.info(f"search backend-processing took {total_time}s - engine-only took {meta.time}s")
    return render_template(
        template_path,
        form=form,
        search_results=results_page,
        search_meta=meta,
        total_time=total_time,
        pagination_links=pagination_links,
        user_errors=user_errors,
    )


def main():
    userInput = input("Fraction: ")
    print(fuel(userInput))

def fuel(input):
    fraction = input.split("/")

    try:
        gauge = int(fraction[0]) / int(fraction[1]) * 100
        if 100 >= gauge > 99:
            return f"F"
        elif 0 <= gauge < 1:
            return f"E"
        elif gauge == 25 or gauge == 50 or gauge == 75:
            return f"{int(gauge)}%"
        else:
            return f"error"
    except:
        return f"error"

if __name__ == "__main__":
    main()


from collections import Counter
class Solution:
    def commonChars(self, A):
        counts = 0

        for i in range(len(A)):
            A[i] = Counter(A[i])

            if i == 0:
                prevk = set(A[i].keys())

                prevDict = dict()
                for k, v in A[i].items():
                    prevDict[k] = [v, float('Inf')]

            key = set(A[i].keys())

            _unionDict = dict()
            _unionKeys = prevk & key
            prevk = _unionKeys

            for k in _unionKeys:

                if A[i][k] >= min(prevDict[k]):

                    _unionDict[k] = min(prevDict[k])

                prevDict[k].append(A[i][k])

        res = []
        for key, value in _unionDict.items():
            current = [key]*value
            res += current

        return res

sol = Solution()
input = ["cool","lock","cook"]

print(sol.commonChars(input))


#!C:\Users\SesayE01\Desktop\Studies\Web Developement\SaloneBizness.com\Projects\salonenewsproject\salonenewsproject\env\Scripts\python.exe
# EASY-INSTALL-ENTRY-SCRIPT: 'tldextract==1.5.1','console_scripts','tldextract'
__requires__ = 'tldextract==1.5.1'
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
    sys.exit(
        load_entry_point('tldextract==1.5.1', 'console_scripts', 'tldextract')()
    )


import discord
from discord.ext import commands

import sqlite3
import json
import os
import aiohttp

from io import BytesIO

class Moderation(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.Cog.listener()
    async def on_guild_join(self, guild):
        # First we set the prefix
        with open("prefixes.json", "r") as f:
            prefixes = json.load(f)

        prefixes[str(guild.id)] = "-"
        with open("prefixes.json", "w") as f:
            json.dump(prefixes, f)

        await self.help(guild.system_channel)

        sql_add(guild)

    @commands.Cog.listener()
    async def on_member_join(self, member):
        greet_channel = sql_get(member.guild, "greet_channel")
        default_role = sql_get(member.guild, "default_role")

        if not (greet_channel is None or greet_channel == "None"):
            channel = self.bot.get_channel(int(greet_channel))
            await channel.send(sql_get(member.guild, 'greet_with').replace('@', f'{member.mention}'))

        if not (default_role is None or default_role == "None"):
            role = member.guild.get_role(int(default_role))
            await member.add_roles(role)

    @commands.command(hidden=True)
    @commands.is_owner()
    async def addgif(self, ctx, file, link):
        interactions = os.listdir("Interactions")
        actions = os.listdir("Actions")

        for filename in interactions:
            if file in filename:
                add_link("Interactions/" + filename, link)
                break

        else:
            for filename in actions:
                if file in filename:
                    add_link("Actions/" + filename, link)
                    break

            else:
                ctx.send("I can't seem to find what command is that gif for")

    @commands.command(aliases=["createemoji", "Createemoji", "Addemote", "createemote", "addemoji", "Addemoji"], brief="addemote <url/emote> <name> to add an emote to your server")
    @commands.has_permissions()
    async def addemote(self, ctx, emote=None, *, name=None):
        if emote is None:
            await ctx.send("Use `addemote <url/emote> <name>` to add an emote in this server !")

        elif name is None or len(name)<2:
            await ctx.send("Emote must have a name at least 2 letters long !")

        else:
            #Grab the emote id to have the link to the image
            if emote.startswith("<") and emote.endswith(">"):
                count = 0
                animated = False
                if emote[1] == "a": animated = True
                while count<2:
                    if emote[0] == ":":
                        count+=1
                    emote=emote[1:]
                emote_id = emote[:-1]
                emote = f"https://cdn.discordapp.com/emojis/{emote_id}.png?size=128"
                if animated:
                    emote = emote.replace("png", "gif")
            else:

                if "gif" in emote: animated = True
                else: animated = False
            url = emote

            async with aiohttp.ClientSession() as ses:

                	async with ses.get(url) as r:
                		try:

                			img_or_gif = BytesIO(await r.read())
                			b_value = img_or_gif.getvalue()
                			if r.status in range(200, 299):

                				emoji = await ctx.guild.create_custom_emoji(image=b_value, name=name.replace(" ", ""))
                				if animated :await ctx.send(f'Done, I just added <a:{name}:{emoji.id}> to the server !')
                				else:await ctx.send(f'Done, I just added <:{name}:{emoji.id}> to the server !')
                				await ses.close()

                			else:
                				await ctx.send(f'Error when making request | {r.status} response. !')
                				await ses.close()

                		except discord.HTTPException:
                 		    await ctx.send('An error occured while adding the emoji \n \
                                Please make sure your image is 256*256 or smaller \n \
                                To avoid bugs like this, use the image link directly')

    @commands.command(aliases=["giverole"], brief="Gives the requested role(s) to the requested user(s)")
    @commands.has_permissions(manage_roles=True)
    async def addrole(self, ctx):
        if ctx.message.member_mentions:

            if ctx.message.role_mentions:

                for member in ctx.message.mentions:

                    for role in ctx.message.role_mentions:

                        try:
                            await member.add_roles(role, reason=f"{ctx.author.name} asked me to")
                        except discord.Forbidden:
                            await ctx.send(f"I do not have permissions to give {role.mention} role to {member.mention}")
                        except:
                            await ctx.send(f"An error occured while giving `{role.name}` role to {member.mention}")

                await ctx.message.add_reaction("\u2705")

            else:
                await ctx.send("Please use `addrole <@member mention> <@role mention>`")

        else:
            await ctx.send(f"Please use `addrole <@member mention> <@role mention>`")

    @commands.command(brief="Deletes the requested number of messages, 5 by default.")
    @commands.has_permissions(manage_messages=True)
    async def clean(self, ctx, number="5"):
        try:
            assert int(number) < 100
            assert int(number) > 0
            await ctx.channel.purge(limit=int(number)+1)
        except:
            pass

    @commands.command(aliases=["h", "Help", "H"], brief="Shows the help menu, which I guess you already saw")
    async def help(self, ctx, *, input=""):
        """Show to help page of the bot"""
        # First of all, we grab the prefix if the command is issued in a server
        # And put the default prefix in case it's not
        a_prefix = "-"

        if ctx.guild:
            with open("prefixes.json", "r") as f:
                prefixes = json.load(f)
                a_prefix = prefixes[str(ctx.guild.id)]
            description = f"My prefix here is `{a_prefix}`\n \n **Have fun playing with me~ ! \n**"

        else:
            description = f"Meow, I like it when you slide in my dms"
        # Now that we have description according to the context, we can start

        # Adapt to include more ways to write the page you want
        if input.lower() in ["n", "neko", "nekotato", "main", "m", "moderation"]:
            input = "main_help"
        elif input.lower() in ["a", "act", "acts", "action"]:
            input = "actions"
        elif input.lower() in ["i", "int", "ints", "interact", "interacts", "interaction"]:
            input = "interactions"

        # If the user is looking for help about a category other than the main one
        # Because the main one has another format
        for cog in self.bot.cogs:

            if input.lower() == cog.lower():
                # We create the embed according to the category
                embed = discord.Embed(title=f"Here's all the {input.lower()} commands I know", color=0xf8e3e1,
                                      description=description)
                commands_list = ""
                # Fill the list of commands in this category
                for command in self.bot.get_cog(cog).get_commands():
                    if not command.hidden:
                        commands_list += f"`{command.name}` | "
                embed.add_field(name="â€‹", value=commands_list[:-3])
                embed.add_field(name="Usage", value=f"`{a_prefix}{self.bot.get_cog(cog).usage_example()}", inline=False)
                break

        else:

            if input == "main_help":
                embed = discord.Embed(title=f"Here are my main commands", color=0xf8e3e1, description=description)
                commands_list = ""
                # Fill the list of commands in the main category
                for command in self.bot.get_cog("Moderation").get_commands():
                    if not command.hidden:
                        commands_list += f"`{command.name}`"
                        commands_list += "â€‚" * (8 - len(command.name))
                        commands_list += f"| {command.brief} \n \n"
                embed.add_field(name="â€‹", value=commands_list[:-2])

            else:
                embed = discord.Embed(color=0xf8e3e1, description=description)

                for cog in self.bot.cogs:
                    commands_list = ""

                    for command in self.bot.get_cog(cog).get_commands():
                        if not command.hidden:
                            commands_list += f"`{command.name}` | "
                    embed.add_field(name=f"ðŸ’®{cog}", value=commands_list[:-3], inline=False)

                embed.add_field(name="â€‹",
                                value=f"**Use** `{a_prefix}help <Category>` **for more information about a category.**",
                                inline=False)

        embed.add_field(name="â€‹",
                        value="[Invite me](https://discord.com/api/oauth2/authorize?client_id=862433335833002045&permissions=85056&scope=bot) \
                            | [Support server](https://discord.gg/MBjkNqaSGW) \
                            | [Vote for me](https://top.gg/bot/862433335833002045/vote)",
                        inline=False)

        embed.set_author(name=f"{self.bot.user.display_name}'s help page", icon_url=self.bot.user.avatar_url)
        await ctx.send(embed=embed)

    @commands.command(aliases=["inv", "Invite", "Inv"], brief="Gives you a link to invite the bot to your own server")
    async def invite(self, ctx):
        embed = discord.Embed(title="Click this to add me to your server !",
                              url="https://discord.com/api/oauth2/authorize?client_id=862433335833002045&permissions=85056&scope=bot",
                              color=0xf8e3e1)

        embed.set_author(name="Nekotato's invite link", icon_url=self.bot.user.avatar_url)
        await ctx.send(embed=embed)

    @commands.command(brief="Enables you to change the prefix of the bot on the server")
    @commands.has_permissions(administrator=True)
    async def prefix(self, ctx, new_prefix=""):
        """To change the prefix of the bot in a server"""
        if (new_prefix.startswith("<:") or new_prefix.startswith("<a:")) and new_prefix.endswith(">") and len(
                new_prefix) > 5:
            await ctx.send("Sorry, to avoid bugs I don't work with that kind of prefix")

        elif new_prefix == "":
            await ctx.send("Sorry, you need to provide me a prefix.")

        else:
            with open("prefixes.json", "r") as f:
                prefixes = json.load(f)

            prefixes[str(ctx.guild.id)] = new_prefix.lower()
            with open("prefixes.json", "w") as f:
                json.dump(prefixes, f)

            await ctx.send(f"Understood, my new prefix here is `{new_prefix}` ~")

    @commands.command(aliases=["takerole"], brief="Removes the requested role(s) away from the requested user(s)")
    @commands.has_permissions(manage_roles=True)
    async def removerole(self, ctx):
        if ctx.message.member_mentions:

            if ctx.message.role_mentions:

                for member in ctx.message.mentions:

                    for role in ctx.message.role_mentions:

                        try:
                            await member.remove_roles(role, reason=f"{ctx.author.name} asked me to")
                        except discord.Forbidden:
                            await ctx.send(f"I do not have permissions to remove {role.mention} role from {member.mention}")
                        except:
                            await ctx.send(f"An error occured while removing `{role.name}` role from {member.mention}")

                await ctx.message.add_reaction("\u2705")

            else:
                await ctx.send("Please use `removerole <@member mention> <@role mention>`")

        else:
            await ctx.send("Please use `removerole <@member mention> <@role mention>`")

    @commands.command(brief="To see and modify my settings in here")
    async def settings(self, ctx):
        embed = discord.Embed(color=0xf8e3e1)

        # First of all, we grab the prefix
        with open("prefixes.json", "r") as f:
            prefixes = json.load(f)
            cur_prefix = prefixes[str(ctx.guild.id)]

        greet_channel = sql_get(ctx.guild, "greet_channel")
        # If the server doesn't have enabled the greetings
        if greet_channel is None or greet_channel == "None":
            value = f"This server didn't enable greetings \n \n" \
                    f"Use `{cur_prefix}greet_here` in any channel and I will send my welcomes there. \n" \
                    f"Use `{cur_prefix}greet_with` <welcome sentence> to set this server's welcome sentence \n Use `@` where you want to mention the user.\n"

        else:
            value = f"My greetings channel here is <#{greet_channel}> \n " \
                    f"Use `{cur_prefix}greet_here` in any channel I can write in to make it the new greetings channel."

            value += "\n \n"

            value += f"My greetings sentence is : \n \n {sql_get(ctx.guild, 'greet_with').replace('@', f'{self.bot.user.mention}')} \n \n" \
                     f"To change it use `{cur_prefix}greet_with` <welcome sentence>, use `@` where you want to mention the user."

        embed.add_field(name="Greetings", value=value, inline=False)

        # Default role part
        default_role = sql_get(ctx.guild, "default_role")
        if default_role is None or default_role == "None":
            value = f"This server doesn't have a default role. \n " \
                    f"Use `{cur_prefix}autorole` to set a role to give people when they join the server."

        else:
            value = f"The current default role in this server is <@&{default_role}> .\n " \
                    f"Use `{cur_prefix}autorole` to set a new role to give people when they join the server."

        embed.add_field(name="Default role", value=value, inline=False)

        embed.add_field(name="â€‹", value="[Invite me](https://discord.com/api/oauth2/authorize?client_id=862433335833002045&permissions=85056&scope=bot) \
                        | [Support server](https://discord.gg/MBjkNqaSGW) \
                        | [Vote for me](https://top.gg/bot/862433335833002045/vote)", inline=False)
        embed.set_author(name="Here are my settings for this server.", icon_url=self.bot.user.avatar_url)
        await ctx.channel.send(embed=embed)

    @commands.command(brief="Gives you an invite to my support server")
    async def support(self, ctx):
        """Sends the author an invite link to the support server in dms"""
        await ctx.author.send("Hey, here's the invite to my support server, I hope you'll find the help you need \n "
                              "https://discord.gg/MBjkNqaSGW")

    @commands.command(aliases=["vot", "Vote", "votes"], brief="Gives you a link to vote for me on top.gg")
    async def vote(self, ctx):
        embed = discord.Embed(title="Click this to vote for me !",
                              url="https://top.gg/bot/862433335833002045/vote",
                              color=0xf8e3e1)

        embed.set_author(name="Nekotato's vote link", icon_url=self.bot.user.avatar_url)
        await ctx.author.send(embed=embed)

    @commands.command(hidden=True)
    @commands.has_permissions(administrator=True)
    async def greet_here(self, ctx):
        cur = base.cursor()
        cur.execute('update settings set greet_channel = ? where server_id = ?', (str(ctx.channel.id), str(ctx.guild.id)))
        cur.close()

        await ctx.message.add_reaction("\u2705")

    @commands.command(hidden=True)
    @commands.has_permissions(administrator=True)
    async def greet_with(self, ctx, *greetings):
        cur = base.cursor()
        cur.execute('update settings set greet_with = ? where server_id = ?', (greetings, str(ctx.guild.id)))
        cur.close()

        await ctx.message.add_reaction("\u2705")

    @commands.command(hidden=True)
    @commands.has_permissions(administrator=True)
    async def autorole(self, ctx):
        if ctx.message.role_mentions and len(ctx.message.role_mentions) == 1:
            cur = base.cursor()
            cur.execute('update settings set default_role = ? where server_id = ?', (ctx.message.role_mentions[0].id, str(ctx.guild.id)))
            cur.close()

            await ctx.message.add_reaction("\u2705")

        else:
            await ctx.send("Please provide the role you want as default")

def add_link(filename, link):
    with open(filename, "a") as f:
        f.write("\n" + link)

def sql_get(server, request):
    cur = base.cursor()

    cur.execute(f"select {request} from settings where server_id = ?", (str(server.id),))
    base.commit()
    result = cur.fetchall()[0][0]

    cur.close()
    return result

def sql_add(server):
    cur = base.cursor()

    my_tuple = (str(server.id), "None", "Welcome @ I hope you'll find here everything you need ~", "None")
    cur.execute("insert into settings(server_id, greet_channel, greet_with, default_role) values(?,?,?,?)", my_tuple)
    base.commit()

    cur.close()

def sql_set(server, request, new):
    cur = base.cursor()

    try:
        cur.execute(f"update settings set {request} = ? where server_id = ?", (new, str(server.id)))
        base.commit()
    except:
        print("Can't set new settings")

    cur.close()

base = sqlite3.connect("nekotato_settings.db")


import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from uncertainties import ufloat
import uncertainties.unumpy as unp

f, UErr,  Uc = np.genfromtxt('data_scripts/frequence.txt', unpack = True)
UErr *= 5
Uc *= 10

U = Uc / UErr

plt.hlines(xmin = f[0], xmax = f[-1], y = max(U) / np.sqrt(2), linestyle = '--', color = 'tab:red', label = r'$\sfrac{U_\text{max}}{\sqrt{2}}$' )
plt.plot(f, U, '.', markersize = 2, label = 'Messwerte')
plt.xscale('log')
plt.yscale('log')

plt.xlabel(r'$\nu   \mathbin{/} \si{\kilo\hertz}$')
plt.ylabel(r'$U     \mathbin{/} \si{\volt}$')
plt.legend(loc = 'center left')

plt.tight_layout(pad=0, h_pad=1.08, w_pad=1.08)
plt.savefig('build/frequence.pdf')
np.savetxt('quotientUcUErr.txt', np.column_stack([f, UErr, Uc, U]), fmt = '%2.2f', header='v, UErr, Uc, U')

L = ufloat(16.78e-3, 0.09e-3)
C = ufloat(2.066e-9, 0.06e-9)
R = ufloat(67.2, 0.2)

wplus =     R / (4 * np.pi * L) + 1 / (2 * np.pi) * unp.sqrt(1 / ( L * C) + R**2 / (4 * L**2))
wminus = -  R / (4 * np.pi * L) + 1 / (2 * np.pi) * unp.sqrt(1 / ( L * C) + R**2 / (4 * L**2))
print(f'Der theoretische Wert für omega+ ist {wplus:.2f} ')
print(f'Der theoretische Wert für omega- ist {wminus:.2f} ')
print(f'Die theoretische Güte beträgt {unp.sqrt(L/C) / R:.2f}')
print(f'Die theoretische Breit ist : {wplus - wminus}')

##


# -*- coding: utf-8 -*-

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5 import QtCore
from tkinter import *
from tkinter.messagebox import *
from ui_layout import Ui_zhu
import gloabl_var as gl
from common import check_verification_code
from common import get_mac_addr

# Widget界面时 ->（QWidget,UI_Form）,QDialog-->(QDialog, Ui_Dialog)，MainWindow类似
class MyWindow(QWidget, Ui_zhu):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.setupUi(self)
        """-
        下面可以写一下初始化操作
        """

def check_permission():
    """

    :return: 1 or 0,  1 success, 0 failed
    """
    root = Tk()
    root.withdraw()  # 隐藏
    try:
        file = open('permission.txt', 'r')
        code = file.readline()
        if 0 == check_verification_code(code):
            showinfo('OPPO Permission', 'verification code error')
            return 0
        else:
            return 1
    except:
        board_serial = get_mac_addr()
        if len(board_serial) == 0:
            board_serial = 'get serial failed'
        f = open('serial.txt', 'w', encoding='utf-8')
        f.write(board_serial)
        f.write('\n')
        f.write('Please send serial file to licensor\n')
        f.close()
        showinfo('OPPO Permission', 'No Permission\nPlease send serial file to licensor for permission')
        return 0

if __name__ == '__main__':
    # global var init

    ret = check_permission()
    if 0 == ret:
        sys.exit()

    gl._init()
    gl.set_value('report_name', "OPPO手机照相效果客观测试报告.xlsx")
    gl.set_value('folder_list',
                 ["ColorChecker", "TE255", "TVLine", "SiemensStar", "DOT", "DeadLeaf",
                  "OECF", "Gray", "OB", "Scroll", "Flicker"])

    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    app = QApplication(sys.argv)
    win = MyWindow()
    gl.set_value('win', win)
    win.show()
    sys.exit(app.exec_())


# 做完特徵工程前的所有準備 (與前範例相同)
import pandas as pd
import numpy as np
import copy
from sklearn.preprocessing import LabelEncoder, MinMaxScaler
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import GradientBoostingClassifier

import warnings
warnings.filterwarnings('ignore')

data_path ='E:\\python\\ML-day100\\data\\'
df = pd.read_csv(data_path + 'titanic_train.csv')

train_Y = df['Survived']
df = df.drop(['PassengerId', 'Survived'] , axis=1)
df.head()

# 因為需要把類別型與數值型特徵都加入, 故使用最簡版的特徵工程
LEncoder = LabelEncoder()
MMEncoder = MinMaxScaler()
for c in df.columns:
    df[c] = df[c].fillna(-1)
    if df[c].dtype == 'object':
        df[c] = LEncoder.fit_transform(list(df[c].values))
    df[c] = MMEncoder.fit_transform(df[c].values.reshape(-1, 1))
df.head()

# 梯度提升樹擬合後, 將結果依照重要性由高到低排序 (note : D27作業中'Ticket'是第一名特徵, 'Age'是數值特徵中排名最高者)
estimator = GradientBoostingClassifier()
estimator.fit(df.values, train_Y)
feats = pd.Series(data=estimator.feature_importances_, index=df.columns)
feats = feats.sort_values(ascending=False)
feats

# 原始特徵 + 梯度提升樹
train_X = MMEncoder.fit_transform(df)
cross_val_score(estimator, train_X, train_Y, cv=5).mean()

# 高重要性特徵 + 梯度提升樹

high_feature = list(feats[:4].index)

train_X = MMEncoder.fit_transform(df[high_feature])
cross_val_score(estimator, train_X, train_Y, cv=5).mean()

# 觀察重要特徵與目標的分布
# 第一名 : Ticket
import seaborn as sns
import matplotlib.pyplot as plt
sns.regplot(x=df['Ticket'], y=train_Y, fit_reg=False)
plt.show()

# 第二名 : Name
sns.regplot(x=df['Name'], y=train_Y, fit_reg=False)
plt.show()

# 製作新特徵看效果

df['Add_char'] = (df['Ticket'] + df['Name']) / 2
df['Multi_char'] = df['Ticket'] * df['Name']
df['GO_div1p'] = df['Ticket'] / (df['Name']+1) * 2
df['OG_div1p'] = df['Name'] / (df['Ticket']+1) * 2

train_X = MMEncoder.fit_transform(df)
cross_val_score(estimator, train_X, train_Y, cv=5).mean()


import numpy as np
import matplotlib.pyplot as plt

epoch_losses = []
losses_avg = []

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def d_sigmoid(x):
    return sigmoid(x) * (1 - sigmoid(x))

def mse_loss(output, labels):
    return np.multiply(output - labels, output - labels)

def d_mse_loss(output, labels):
    return 2 * (output - labels)

class NeuralNet:
    def __init__(self, layer_sizes, learning_rate, activation=sigmoid, d_activation=d_sigmoid, loss=mse_loss,
                 d_loss=d_mse_loss):
        self.activation = activation
        self.d_activation = d_activation
        self.loss = loss
        self.d_loss = d_loss
        self.learning_rate = learning_rate
        self.weights = [2 * np.random.random((layer_sizes[i], layer_sizes[i - 1])) - 1 for i in
                        range(1, len(layer_sizes))]
        self.biases = [2 * np.random.random(layer_sizes[i]) - 1 for i in range(1, len(layer_sizes))]

    def feedforward(self, x):
        z_all = []
        a_all = [x]
        cur_a = x
        for w, b in zip(self.weights, self.biases):
            z = np.dot(w, cur_a) + b
            z_all.append(z)
            a = self.activation(z)
            a_all.append(a)
            cur_a = a

        return z_all, a_all

    def backprop(self, x, z_all, a_all, y):
        d_biases = np.zeros_like(self.biases)
        d_weights = np.zeros_like(self.weights)

        d_aL = self.d_loss(a_all[-1], y)
        d_out_zL = self.d_activation(z_all[-1])
        d_zL = d_aL * d_out_zL

        d_biases[-1] = d_zL
        d_weights[-1] = np.dot(d_zL.reshape((-1, 1)), a_all[-2].reshape((1, -1)))

        d_zl = d_zL

        for l in range(len(self.weights) - 2, -1, -1):
            d_al = np.dot(d_zl, self.weights[l + 1])
            d_al_zl = self.d_activation(z_all[l])
            d_zl = d_al * d_al_zl

            d_weights[l] = np.dot(d_zl.reshape((-1, 1)), a_all[l].reshape((1, -1)))
            d_biases[l] = d_zl

        return d_weights, d_biases

    def step(self, x, y):
        z_all, a_all = self.feedforward(x)
        d_weights, d_biases = self.backprop(x, z_all, a_all, y)

        loss = self.loss(a_all[-1], y)
        epoch_losses.append(loss)

        self.weights -= self.learning_rate * d_weights
        self.biases -= self.learning_rate * d_biases

    def train(self, x, y, epochs):
        for epoch in range(epochs):
            epoch_losses.clear()
            for i in range(len(x)):
                self.step(x[i], y[i])
            losses_avg.append(sum(epoch_losses) / 4)

    def predict(self, x):
        _, a_all = self.feedforward(x)
        print("input={}, predicted={}".format(x, a_all[-1]))

x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 1, 1, 0])
net = NeuralNet(layer_sizes=(2, 5, 1), learning_rate=0.1)
net.train(x, y, 6000)

net.predict([0, 0])
net.predict([0, 1])
net.predict([1, 0])
net.predict([1, 1])

plt.plot(losses_avg)
plt.show()


from common.parse_tex import (
    BeginDocumentExtractor,
    DocumentclassExtractor,
    EquationExtractor,
    MacroExtractor,
    PhraseExtractor,
    extract_plaintext,
)
from common.types import MacroDefinition
from entities.citations.extractor import BibitemExtractor
from entities.sentences.extractor import SentenceExtractor

def test_extract_plaintext_with_equations():
    plaintext = extract_plaintext(
        "main.tex", "This sentence includes a symbol $x$ and equation $$y = x$$."
    )
    assert plaintext == (
        "This sentence includes a symbol EQUATION_DEPTH_0_START x EQUATION_DEPTH_0_END "
        + "and equation EQUATION_DEPTH_0_START y = x EQUATION_DEPTH_0_END."
    )

def test_extract_plaintext_with_nested_equations():
    plaintext = extract_plaintext(
        "main.tex", r"This sentence contains an equation \(x = \textrm{$y$}\)."
    )
    assert plaintext == (
        r"This sentence contains an equation EQUATION_DEPTH_0_START x = \textrm{ "
        + "EQUATION_DEPTH_1_START y EQUATION_DEPTH_1_END } EQUATION_DEPTH_0_END."
    )

def test_extract_plaintext_no_add_space_before_equation_possessive():
    plaintext = extract_plaintext(
        "main.tex", "This sentence includes a possessive equation $x$'s."
    )
    assert (
        plaintext
        == r"This sentence includes a possessive equation EQUATION_DEPTH_0_START x "
        + "EQUATION_DEPTH_0_END's."
    )

def test_extract_plaintext_remove_comments():
    plaintext = extract_plaintext("main.tex", "% comment\nText% comment\n% comment")
    assert plaintext == "Text"

def test_extract_plaintext_skip_input():
    plaintext = extract_plaintext(
        "main.tex", "\n".join([r"\input file", r"\input{file}", r"\include{file}"])
    )
    assert plaintext.isspace()

def test_extract_plaintext_leave_initial_intact():
    tex = "\\documentclass{article}"
    plaintext = extract_plaintext("main.tex", tex)
    assert plaintext.initial == tex

def test_extract_plaintext_consolidate_periods():
    plaintext = extract_plaintext("main.tex", "Sentence. .. Next sentence.")
    assert plaintext == "Sentence. Next sentence."

def test_extract_plaintext_consolidate_periods_across_groups():
    plaintext = extract_plaintext("main.tex", "\\footnote{Sentence.}. Next sentence.")
    assert plaintext == "Sentence. Next sentence."

def test_extract_plaintext_separate_section_header():
    plaintext = extract_plaintext(
        "main.tex", "\n".join(["Line 1", r"\section{Section header}", "Line 3"])
    )
    assert plaintext == "\n".join(["Line 1", "", "Section header.", "", "Line 3"])

def test_extract_phrases():
    extractor = PhraseExtractor(["word", "two-token phrase"])
    phrases = list(
        extractor.parse(
            "main.tex", "This sentence contains word and a two-token phrase."
        )
    )

    phrase1 = phrases[0]
    assert phrase1.start == 23
    assert phrase1.end == 27
    assert phrase1.text == "word"

    phrase2 = phrases[1]
    assert phrase2.start == 34
    assert phrase2.end == 50
    assert phrase2.text == "two-token phrase"

def test_extract_phrases_from_formatted_text():
    extractor = PhraseExtractor(["two-token phrase"])
    phrases = list(
        extractor.parse(
            "main.tex", r"In this \textbf{two-token phrase}, something happens."
        )
    )
    assert len(phrases) == 1

def test_extract_phrases_containing_ampersands():
    # This example is from arXiv paper 1811.11889.
    extractor = PhraseExtractor(["D&M"])
    phrases = list(extractor.parse("main.tex", r"This sentence contains D\&M."))
    assert len(phrases) == 1
    assert phrases[0].text == "D&M"
    assert phrases[0].tex == r"D\&M"

def test_extract_phrases_starting_with_symbol():
    # This example is from arXiv paper 1811.11889.
    extractor = PhraseExtractor(["+D&M"])
    phrases = list(extractor.parse("main.tex", r"This sentence contains +D\&M."))
    assert len(phrases) == 1
    assert phrases[0].text == "+D&M"

def test_extract_phrase_containing_single_letter():
    extractor = PhraseExtractor(["T"])
    phrases = list(extractor.parse("main.tex", "This sentence contains the letter T."))
    assert len(phrases) == 1
    assert phrases[0].text == "T"

def test_extract_sentences():
    extractor = SentenceExtractor(from_named_sections_only=False)
    sentences = list(
        extractor.parse(
            "main.tex",
            "This is the first \\macro[arg]{sentence}. This is the second sentence.",
        )
    )
    assert len(sentences) == 2

    sentence1 = sentences[0]
    assert sentence1.start == 0
    assert sentence1.end == 40
    assert sentence1.text == "This is the first argsentence."

    sentence2 = sentences[1]
    assert sentence2.start == 41
    assert sentence2.end == 69
    assert sentence2.text == "This is the second sentence."

def test_ignore_periods_in_equations():
    extractor = SentenceExtractor(from_named_sections_only=False)
    sentences = list(
        extractor.parse("main.tex", "This sentence has an $ equation. In $ the middle.")
    )
    assert len(sentences) == 1
    assert sentences[0].text == (
        "This sentence has an EQUATION_DEPTH_0_START equation. In EQUATION_DEPTH_0_END "
        + "the middle."
    )

def test_sentence_splitting_end_points():
    extractor = SentenceExtractor(from_named_sections_only=False)
    sentences = list(
        extractor.parse(
            "main.tex",
            "This is a sentence. Next we describe two items. 1) The first item. 2) The second item.",
        )
    )

    assert len(sentences) == 4
    sentence_end_points = [[0, 19], [20, 47], [48, 66], [67, 86]]
    for i, [start, end] in enumerate(sentence_end_points):
        assert sentences[i].start == start
        assert sentences[i].end == end

def test_sentence_splitting_end_points_and_more_text():
    extractor = SentenceExtractor(from_named_sections_only=False)
    sentences = list(
        extractor.parse(
            "main.tex",
            "This sentence. has extra. text. 1. first 2. second 3. third. And some extra. stuff.",
        )
    )
    assert len(sentences) == 8
    sentence_end_points = [
        [0, 14],
        [15, 25],
        [26, 31],
        [32, 40],
        [41, 50],
        [51, 60],
        [61, 76],
        [77, 83],
    ]
    for i, [start, end] in enumerate(sentence_end_points):
        assert sentences[i].start == start
        assert sentences[i].end == end

def test_combine_sentence_tex_following_latex_linebreak_conventions():
    extractor = SentenceExtractor(from_named_sections_only=False)
    sentences = list(
        extractor.parse(
            "main.tex",
            "\n".join(
                [
                    # All on one line.
                    (
                        r"This is the first sentence.\\"
                        + r"This is the second sentence.\linebreak "
                        + "This is the third sentence."
                    ),
                    "",
                    "This is the fourth sentence.",
                    " ",
                    # With only a single newline, consecutive lines should be considered the same sentence.
                    "This is the fifth sentence, which is written on multiple",
                    "lines.",
                ]
            ),
        )
    )
    assert sentences[0].text == "This is the first sentence."
    assert sentences[0].end == 27
    assert sentences[1].text == "This is the second sentence."
    assert sentences[2].text == "This is the third sentence."
    assert sentences[3].text == "This is the fourth sentence."
    assert (
        sentences[4].text
        == "This is the fifth sentence, which is written on multiple lines."
    )
    assert len(sentences) == 5

def test_sentence_from_within_command():
    extractor = SentenceExtractor(from_named_sections_only=False)
    # The space in the start of this sentence is important, as in an earlier version of the
    # code, this space caused extraction to fail.
    sentences = list(extractor.parse("main.tex", r" \textit{Example sentence.}"))
    assert sentences[0].text == "Example sentence."
    assert sentences[0].tex == "Example sentence."
    assert sentences[0].start == 9
    assert sentences[0].end == 26

def test_sentence_includes_preceding_equation():
    extractor = SentenceExtractor(from_named_sections_only=False)
    # This was a specific case seen in an example paper.
    sentences = list(
        extractor.parse("main.tex", "Sentence 1.\n\\[x\\]\nstarts the sentence.")
    )
    assert sentences[1].tex == "\\[x\\]\nstarts the sentence."
    assert sentences[1].start == 12
    assert sentences[1].end == 38

def test_extract_equation_from_dollar_sign():
    extractor = EquationExtractor()
    equations = list(extractor.parse("main.tex", "$x + y$"))
    assert len(equations) == 1

    equation = equations[0]
    assert equation.start == 0
    assert equation.content_start == 1
    assert equation.end == 7
    assert equation.content_tex == "x + y"
    assert equation.tex == "$x + y$"

def test_extract_equation_from_dollar_sign_after_newline():
    # This pattern was observed in arXiv paper 1703.00102.
    extractor = EquationExtractor()
    equations = list(extractor.parse("main.tex", r"\\$x$"))
    assert len(equations) == 1

def test_extract_equation_from_equation_environment():
    extractor = EquationExtractor()
    equations = list(extractor.parse("main.tex", "\\begin{equation}x\\end{equation}"))
    assert len(equations) == 1

    equation = equations[0]
    assert equation.start == 0
    assert equation.content_start == 16
    assert equation.end == 31
    assert equation.content_tex == "x"
    assert equation.tex == "\\begin{equation}x\\end{equation}"

def test_extract_equation_from_star_environment():
    extractor = EquationExtractor()
    equations = list(extractor.parse("main.tex", "\\begin{equation*}x\\end{equation*}"))
    assert len(equations) == 1

    equation = equations[0]
    assert equation.start == 0
    assert equation.end == 33

def test_extract_equation_environment_with_argument():
    extractor = EquationExtractor()
    equations = list(extractor.parse("main.tex", "\\begin{array}{c}x\\end{array}"))
    assert len(equations) == 1

    equation = equations[0]
    assert equation.content_start == 16

def test_extract_equation_from_double_dollar_signs():
    extractor = EquationExtractor()
    equations = list(extractor.parse("main.tex", "$$x$$"))
    assert len(equations) == 1

    equation = equations[0]
    assert equation.start == 0
    assert equation.end == 5

def test_dont_extract_equation_from_command_argument_brackets():
    extractor = EquationExtractor()
    equations = list(extractor.parse("main.tex", "\\documentclass[11pt]{article}"))
    assert len(equations) == 0

def test_extract_equation_from_brackets():
    extractor = EquationExtractor()
    equations = list(extractor.parse("main.tex", "\\[x + y\\]"))
    assert len(equations) == 1

    equation = equations[0]
    assert equation.start == 0
    assert equation.content_start == 2
    assert equation.end == 9

def test_extract_nested_equations():
    extractor = EquationExtractor()
    equations = list(
        extractor.parse("main.tex", "$x + \\hbox{\\begin{equation}y\\end{equation}}$")
    )
    assert len(equations) == 2
    outer = next(filter(lambda e: e.start == 0, equations))
    assert outer.end == 44
    inner = next(filter(lambda e: e.start == 11, equations))
    assert inner.end == 42

def test_handle_unclosed_environments():
    extractor = EquationExtractor()
    equations = list(extractor.parse("main.tex", "$x + \\hbox{\\begin{equation}y}$"))
    assert len(equations) == 1
    equation = equations[0]
    assert equation.start == 0
    assert equation.end == 30

def test_ignore_escaped_dollar_sign():
    extractor = EquationExtractor()
    equations = list(extractor.parse("main.tex", "\\$\\$"))
    assert len(equations) == 0

def test_extract_begindocument():
    extractor = BeginDocumentExtractor()
    tex = "\\RequirePackage[hyperindex]{hyperref}\n\\begin{document}"
    begindocument = extractor.parse(tex)
    assert begindocument.start == 38
    assert begindocument.end == 54

def test_extract_documentclass_after_comment_ending_with_whitespace():
    extractor = DocumentclassExtractor()
    tex = "\n\n%\\documentclass{IEEEtran}    \n\\documentclass{article}"
    documentclass = extractor.parse(tex)
    assert documentclass is not None

def test_documentclass_after_macro():
    # In some TeX files, the documentclass isn't declared until after some initial macros.
    # We still want to detect the documentclass in these documents.
    extractor = DocumentclassExtractor()
    tex = "\\def\\year{2020}\n\\documentclass{article}"
    documentclass = extractor.parse(tex)
    assert documentclass is not None

def test_extract_bibitems():
    tex = "\n".join(
        [
            "\\bibitem[label]{key1}",
            "token1",
            "\\newblock \\emph{token2}",
            "\\newblock token3",
            "\\bibitem[label]{key2}",
            "token4",
            "\\newblock \\emph{token5}",
        ]
    )
    extractor = BibitemExtractor()
    bibitems = list(extractor.parse(tex))
    assert len(bibitems) == 2
    assert bibitems[0].id_ == "key1"
    assert bibitems[0].text == "token1 token2 token3"
    assert bibitems[1].id_ == "key2"
    assert bibitems[1].text == "token4 token5"

def test_extract_bibitem_tokens_from_curly_braces():
    tex = "\n".join(["\\bibitem[label]{key1}", "token1 {token2} {token3}",])
    extractor = BibitemExtractor()
    bibitems = list(extractor.parse(tex))
    assert len(bibitems) == 1
    assert bibitems[0].id_ == "key1"
    assert bibitems[0].text == "token1 token2 token3"

def test_extract_bibitems_from_environment():
    tex = "\n".join(
        [
            "\\begin{thebibliography}",
            "\\bibitem[label]{key1}",
            "token1",
            "\\end{thebibliography}",
        ]
    )
    extractor = BibitemExtractor()
    bibitems = list(extractor.parse(tex))
    assert len(bibitems) == 1
    assert bibitems[0].id_ == "key1"
    assert bibitems[0].text == "token1"

def test_extract_bibitem_stop_at_newline():
    tex = "\n".join(
        ["\\bibitem[label]{key1}", "token1", "", "text after bibliography (to ignore)"]
    )
    extractor = BibitemExtractor()
    bibitems = list(extractor.parse(tex))
    assert len(bibitems) == 1
    assert bibitems[0].id_ == "key1"
    assert bibitems[0].text == "token1"

def test_extract_bibitem_include_hyperref_contents():
    tex = "\n".join(
        ["\\bibitem[label]{key1}", r"token1 \href{https://url.com}{token2}"]
    )
    extractor = BibitemExtractor()
    bibitems = list(extractor.parse(tex))
    assert len(bibitems) == 1
    assert bibitems[0].text == "token1 token2"

def test_extract_bibitem_wrapping_key():
    tex = "\n".join([r"\bibitem[label]%", r"    {key}", r"    token"])
    extractor = BibitemExtractor()
    bibitems = list(extractor.parse(tex))
    assert len(bibitems) == 1
    assert "token" in bibitems[0].text

def test_extract_bibitem_with_brackets_in_label():
    tex = "\n".join([r"\bibitem[label{[]}]{key}", r"token"])
    extractor = BibitemExtractor()
    bibitems = list(extractor.parse(tex))
    assert len(bibitems) == 1
    assert "token" in bibitems[0].text

def test_extract_macro():
    tex = "\\macro"
    extractor = MacroExtractor()
    macros = list(extractor.parse(tex, MacroDefinition("macro", "")))
    assert len(macros) == 1
    assert macros[0].start == 0
    assert macros[0].end == 6

def test_extract_macro_with_delimited_parameter():
    tex = "\\macro arg."
    extractor = MacroExtractor()
    macros = list(extractor.parse(tex, MacroDefinition("macro", "#1.")))
    assert len(macros) == 1
    assert macros[0].start == 0
    assert macros[0].end == 11
    assert macros[0].tex == "\\macro arg."

def test_extract_macro_with_undelimited_parameter():
    # the scanner for undelimited parameter '#1' should match the first non-blank token 'a'.
    tex = "\\macro  a"
    extractor = MacroExtractor()
    macros = list(extractor.parse(tex, MacroDefinition("macro", "#1")))
    assert len(macros) == 1
    assert macros[0].start == 0
    assert macros[0].end == 9
    assert macros[0].tex == "\\macro  a"

def test_extract_macro_balance_nested_braces_for_argument():
    tex = "\\macro{{nested}}"
    extractor = MacroExtractor()
    macros = list(extractor.parse(tex, MacroDefinition("macro", "#1")))
    assert len(macros) == 1
    assert macros[0].start == 0
    assert macros[0].end == 16
    assert macros[0].tex == "\\macro{{nested}}"


from app.dto.api_response.galaxy_type import GalaxyType
from fastapi.exceptions import HTTPException
from fastapi import File, UploadFile
from PIL import Image
from typing import Tuple
import io
import numpy as np
from app.proxies.tflow_serving_proxy import TFlowServingProxy

async def classify_galaxy_handler(image, classifier) -> GalaxyType:
    validate_image(image)
    prepared_image = prepare_image(image)
    category_idx, confidence = await classify_image(prepared_image, classifier)
    return GalaxyType.from_classification(category_idx, confidence)

def validate_image(image : UploadFile) -> None:
    if image.content_type not in ["image/jpeg", "image/png"]:
        raise HTTPException(
            status_code = 415,
            detail = "Unsupported file provided. Please provide a JPEG or PNG image.",
        )

def prepare_image(image : UploadFile) -> np.ndarray:
    image_bytes = image.file.read()
    img = Image.open(io.BytesIO(image_bytes))
    img = img.resize((32, 32), Image.BILINEAR)
    img = img.convert("RGB")
    img = np.array(img) / 255.0
    return img

def parse_results(results : np.ndarray) -> Tuple[int, float]:
    category = int(np.argmax(results) + 1)
    return category, results[category - 1]

async def classify_image(image : np.ndarray, classifier : TFlowServingProxy) -> Tuple[int, float]:
    classifier_results = await classifier.predict(image)
    return parse_results(classifier_results)


"""
    PROJECT    : Outer billiards visualization project.
    FILE       : polygon.py
    AUTHOR     : Andrey Dmitrenko.
    PURPOSE    : The polygon class implementation module.
    LAST UPDATE: 20.05.2021.
"""

from math import pi, sin, cos, floor

from render import *
from ABsqrtN import ABsqrtN
from point import *

'''
    The polygon representation class.

    Fields:
        points (point[]): The array of the (x, y)-tuples
                          representing each vertex coordinates.
        ccosi (tuple): The cosine and sine of central polygon angles.
        cosi (tuple): The cosine and sine of the polygons angles.

    Methods:
        __init__(points, cosi, n_for_sqrt): The constructor.
        draw(color): Draw the polygon on the screen.
        static regular(n): Create the regular polygon with n vertices.
'''
class polygon:
    '''
        The polygon class constructor.
        Arguments:
            points (tuple[]): The array of the coordinates of the vertices.
            ccosi (tuple): The cosine and sine of the central polygon angle.
            cosi (tuple): The cosine and sine of the polygon angles.
            n_for_sqrt (int): The number under the radical for ABsqrtN-polygons.
    '''
    def __init__(self, points, ccosi=None, cosi=None, n_for_sqrt=0):
        if ccosi is None:
            ang = 2 * pi / len(points)
            self.ccosi = (cos(ang), sin(ang))
        else:
            self.ccosi = ccosi

        if cosi is None:
            ang = (len(points) - 2) * pi / len(points)
            self.cosi = (cos(ang), sin(ang))
        else:
            self.cosi = cosi

        self.points = [point(xy[0], xy[1], n_for_sqrt) for xy in points]
    # End of '__init__' function

    '''
        Draw the polygon on the screen.
        Arguments:
            rnd (render): The rendering context to draw in.
            color (tuple): 3-component RGB color to draw with.
        Returns: None.
    '''
    def draw(self, rnd, color):
        pygame.draw.polygon(rnd.screen, color,
                            list(map(lambda p: rnd.cs.to_screen((float(p.x), float(p.y))), self.points)))
    # End of 'draw' function

    '''
        Create a regular polygon of a given number of vertices and side of the length 1.
        Arguments:
            n (int): The number of polygon vertices.
        Returns:
            (polygon) A regular polygon with n vertices.
    '''
    @staticmethod
    def regular(n):
        if n == 3:
            return polygon([(ABsqrtN(3, 0), ABsqrtN(3, 0, 1 / 3)),
                            (ABsqrtN(3, 1 / 2), -ABsqrtN(3, 0, 1 / 6)),
                            (ABsqrtN(3, -1 / 2), -ABsqrtN(3, 0, 1 / 6))],
                           (-1 / 2, ABsqrtN(3, 0, 1) / 2), (1 / 2, ABsqrtN(3, 0, 1) / 2), 3)
        elif n == 4:
            return polygon([(ABsqrtN(2, -1 / 2), ABsqrtN(2, 1 / 2)),
                            (ABsqrtN(2, 1 / 2), ABsqrtN(2, 1 / 2)),
                            (ABsqrtN(2, 1 / 2), ABsqrtN(2, -1 / 2)),
                            (ABsqrtN(2, -1 / 2), ABsqrtN(2, -1 / 2))],
                           (0, 1), (0, 1), 2)
        elif n == 6:
            return polygon([(ABsqrtN(3, 1), ABsqrtN(3, 0)),
                            (ABsqrtN(3, 1 / 2), -ABsqrtN(3, 0, 1 / 2)),
                            (ABsqrtN(3, -1 / 2), -ABsqrtN(3, 0, 1 / 2)),
                            (ABsqrtN(3, -1), ABsqrtN(3, 0)),
                            (ABsqrtN(3, -1 / 2), ABsqrtN(3, 0, 1 / 2)),
                            (ABsqrtN(3, 1 / 2), ABsqrtN(3, 0, 1 / 2))],
                           (1 / 2, ABsqrtN(3, 0, 1) / 2), (-1 / 2, ABsqrtN(3, 0, 1) / 2), 3)
        elif n == 8:
            return polygon([(ABsqrtN(2, 1) / 2,  ABsqrtN(2, 1, 1) / 2),
                            (ABsqrtN(2, 1, 1) / 2,  ABsqrtN(2, 1) / 2),
                            (ABsqrtN(2, 1, 1) / 2, ABsqrtN(2, -1) / 2),
                            (ABsqrtN(2, 1) / 2, -ABsqrtN(2, 1, 1) / 2),

                            (ABsqrtN(2, -1) / 2, -ABsqrtN(2, 1, 1) / 2),
                            (-ABsqrtN(2, 1, 1) / 2, ABsqrtN(2, -1) / 2),
                            (-ABsqrtN(2, 1, 1) / 2, ABsqrtN(2, 1) / 2),
                            (ABsqrtN(2, -1) / 2,  ABsqrtN(2, 1, 1) / 2)],
                           (ABsqrtN(2, 0, 1) / 2, ABsqrtN(2, 0, 1) / 2),
                           (-ABsqrtN(2, 0, 1) / 2, ABsqrtN(2, 0, 1) / 2), 2)
        else:
            mul = 2 * sin(pi / n)
            return polygon([(cos(-2 * pi / n * (i + floor(3 * n / 4))) / mul,
                             sin(-2 * pi / n * (i + floor(3 * n / 4))) / mul) for i in range(0, n)])
    # End of 'regular' function
# End of 'polygon' class

# END OF 'polygon.py' FILE


# Будем искать кол-во пар числе, произведение которых делится на 26
with open('../files/type3.txt') as file:
    text = file.read().split('\n')
    cnt = int(text[0])
    count2, count13, count26 = 0, 0, 0
    for i in range(1, cnt + 1):
        num = int(text[i])
        if num % 26 == 0:
            count26 += 1
        elif num % 13 == 0:
            count13 += 1
        elif num % 2 == 0:
            count2 += 1
print(count2 * count13 + count26 * (count26 - 1) / 2 + count26 * (cnt - count26))


import argparse
import sys
import pathlib
import time
import re
import yaml

import requests
import defusedxml.ElementTree as ET
import libarchive.public

BASE_REPO_URL = "http://download.qt.io/online/qtsdkrepository"

CONFIG = {}

def get_xml(url):
    text = requests.get(url).text
    return ET.fromstring(text)

packages={}
urls={}

def add_package(package, url):
    global packages, urls

    name = package.find("Name").text

    packages[name] = package
    urls[name] = url

def install_package(package_name):
    global CONFIG, urls

    if package_name in CONFIG["ignore"]:
        return

    if package_name not in packages:
        print("Package '{}' not found".format(package_name))
        exit(1)

    package = packages[package_name]

    dependencies = package.find("Dependencies")

    if dependencies is not None:
        for requirement in dependencies.text.split(", "):
            install_package(requirement)

    archives = package.find("DownloadableArchives")

    if archives is not None:
        if archives.text is not None:
            for archive in archives.text.split(", "):

                if package_name in CONFIG["config"]:
                    if CONFIG["config"][package_name]["ignore_archives"]:
                        ignored = False
                        for regex in CONFIG["config"][package_name]["ignore_archives"]:
                            if re.match(regex, archive):
                                ignored = True
                                break

                        if ignored:
                            print("Ignoring {}...".format(archive))
                            continue

                url = urls[package_name]+"/"+package_name+"/"+package.find("Version").text+archive
                print("Downloading {}...".format(url))

                r = requests.get(url)

                print("Extracting...")

                for entry in libarchive.public.memory_pour(r.content):
                    pass

def add_repository(url):
    global args

    repo = get_xml(url+"/Updates.xml")

    # Add repositories
    for repo in repo.iter("Repository"):

        url = repo.attrib["url"]
        action = repo.attrib["action"]
        displayname = repo.attrib["displayname"]

        if action != "add":
            continue

        if args.verbose:
            print("Adding '{}'...".format(repo.attrib["displayname"]))

        add_repository(url)

    # Add packages
    for package in repo.iter("PackageUpdate"):
        add_package(package, url)

parser = argparse.ArgumentParser(description="Create a minimal Qt install")

parser.add_argument("manifest", type=str)
parser.add_argument("--verbose", action="store_true")

args = parser.parse_args()

stream = open(args.manifest, "r")
CONFIG = yaml.load(stream)

print("Parsing repositories (this may take a while)...")
for repo in CONFIG["repos"]:
    add_repository(BASE_REPO_URL + "/" + CONFIG["platform"] + "/" + repo)

print("Done. {} packages found.".format(len(packages)))

for package in CONFIG["packages"]:
    install_package(package)


 # Metabolic Equations for Resting Metabolic Rate
from collections import namedtuple
from inspect import getargspec

# Metabolic Equations, Tuples with Meta Info, Constants

def mifflin(weight=None, height=None, age=None, sex=None, units_system=None):
    """Basal metabolic rate in calories
    based on weight in kg, height in cm, and
    sex (male = 1, female = 0)
    """
    if units_system is 'Imperial':
        height = height * 2.54 # inches to cm
        weight = weight * 0.453592 # lbs to kg

    if sex is 'Male':
        sex = 1
    else:
        sex = 0

    return 9.99 * weight + 6.25 * height - 4.92 * age + 166 * sex - 161

def harris_benedict(weight=None, height=None, age=None, sex=None, units_system=None):
    """Resting metabolic rate in calories
    based on weight in kg, height in cm, and
    sex.
    """
    if units_system is 'Imperial':
        height = height * 2.54 # inches to cm
        weight = weight * 0.453592 # lbs to kg

    if sex is 'Male':
        return 66.5 + 13.75 * weight + 5.003 * height - 6.755 * age
    else:
        return 655.1 + 9.563 * weight + 1.850 * height - 4.676 * age

def cunningham(weight=None, bodyfat=None, units_system=None):
    """Resting metabolic rate in calories
    based on weight in kg and percent body fat
    """

    if units_system is 'Imperial':
        weight = weight * 0.453592 # lbs to kg

    return (weight - weight * bodyfat * 0.01) * 21.6 + 500

def schofield(age=None, weight=None, sex=None, units_system=None):
    """Resting metabolic rate based on on weight in kg, age, and
    sex (male = 1, female = 0)
    """

    if units_system is 'Imperial':
        weight = weight * 0.453592 # lbs to kg

    # Females
    if sex is 'Female':
        if age >= 60:
            return 9.082 * weight + 658.5
        if age >= 30 and age < 60:
            return 8.126 * weight + 845.6
        if age >= 18 and age < 30:
            return 14.818 * weight + 486.6
        if age >= 10 and age < 18:
            return 13.384 * weight + 692.6
        if age >= 3 and age < 10:
            return 20.315 * weight + 485.9

    # Males
    else:
        if age >= 60:
            return 11.711 * weight + 587.7
        if age >= 30 and age < 60:
            return 11.472 * weight + 873.1
        if age >= 18 and age < 30:
            return 15.057 * weight + 692.2
        if age >= 10 and age < 18:
            return 17.686 * weight + 658.2
        if age >= 3 and age < 10:
            return 22.706 * weight + 504.3

# Tuples with Associated Data

# better to put as separate variable? or use _fields protected method?
tuple_fields = ['name', 'equation', 'standard_error',
    'parameters', 'description', 'references', 'age_range', 'weight_range',
    'height_range', 'bodyfat_range']

T = namedtuple('equation_tuple', tuple_fields)

# not sure if this works w/ multiple lines
# T = namedtuple('equation_tuple','Name Equation Standard_Error Parameters Description',
#     'References Age_Range Weight_Range Height_Range')

mifflin_T = T(
    name = "Mifflin St Jeor",
    equation = mifflin,
    standard_error = (0.1),
    # parameters = getargspec(mifflin).args, # better way ?
    parameters = ['weight', 'age', 'height', 'sex', 'units_system'],
    description = None,
    references = None,
    age_range = (18,80),
    weight_range = (30, 200),
    height_range = (122,272),
    bodyfat_range = None
    )

harris_benedict_T = T(
    name = "Harris Benedict",
    equation = harris_benedict,
    standard_error = (0.1),
    parameters = ['weight', 'age', 'height', 'sex', 'units_system'],
    description = None,
    references = None,
    age_range = (18,80),
    weight_range = (30,200),
    height_range = (122,272),
    bodyfat_range = None
    )

cunningham_T = T(
    name = "Cunningham",
    equation = cunningham,
    standard_error = (0.1),
    parameters = ['weight', 'bodyfat', 'units_system'],
    description = 'For bodybuilders with low percent bodyfat.',
    references= None,
    age_range = None,
    weight_range = (30,200),
    height_range = None,
    bodyfat_range = (4,25)
    )

schofield_T = T(
    name = "Schofield",
    equation = schofield,
    standard_error = (0.1),
    parameters = ['weight', 'age', 'units_system'],
    description = 'WHO',
    references = None,
    age_range = (3,80),
    weight_range = (30, 330),
    height_range = None,
    bodyfat_range = None
    )

# also include error, age range, weight range?, height range? in tuple?

# met_eq_functions = ['mifflin', 'harris_benedict', 'cunningham', 'schofield']

met_eq_tuples = [mifflin_T, harris_benedict_T, cunningham_T, schofield_T]
met_eq_functions = [eq.name for eq in met_eq_tuples]
labels = [eq.name for eq in met_eq_tuples]
eq_tup_D = dict(zip(met_eq_functions, met_eq_tuples))

sex_values = ['Male', 'Female']

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

def cm_to_inches(cm):
    return round(0.3937 * cm)

def kg_to_lb(kg):
    return round(2.20462 * kg)

def inches_to_cm(inches):
    return round(2.54 * inches)

def lb_to_kg(lb):
    return round(0.453592 * lb)

conversion_D = {'kg': lb_to_kg, 'lbs': kg_to_lb,
    'cm': inches_to_cm, 'inches': cm_to_inches}

def bmi(weight, height):
    return round(weight / (0.01 * 0.01 * height * height))

def underweight(bmi):
    return bmi < 19


"""
This is where you set up the database and the models you need

In a larger app, you might split out the models to different
files, but in this case, it's OK to put it all here
"""

# pylint: disable=invalid-name

from pathlib import Path
import peewee as pw

HERE = Path(__file__).parent

DEFAULT_DB_NAME = "the_database.db"

def get_models():
    """
    returns a list of the models you have defined

    This is in a function so that the models can be defined
    afeter this function

    You need to add the models you want to use to this list
    """
    return [User]

def start_database(filename=None, clear=False):
    """
    Setup and return a database to use for the models

    If called with no arguments, it will set up a SQLlite database
    using the DEFAULT_DB_NAME, in the dir this file is in.

    :param filename: name of DB file, or ":memory:" for in=memory temp DB

    :param clear=False: Whether to clear out the old db and return an
                        empty one.

    """
    # Create the Database
    if filename == ":memory:":
        db = pw.SqliteDatabase(':memory:',
                               pragmas={'foreign_keys': 1}
                               )
    else:
        if filename is None:
            filename = DEFAULT_DB_NAME
        if clear:
            Path(filename).unlink(missing_ok=True)
        db = pw.SqliteDatabase(HERE / filename,
                               pragmas={'foreign_keys': 1}
                               )

    # Initialize the database
    # If the file exists and is already populated, then
    # this will initialize with the existing data

    models = get_models()

    # this dynamically binds the database to the models
    db.bind(models,
            bind_refs=False,
            bind_backrefs=False)
    db.connect()
    db.create_tables(models)

    # The initialized database is returned for use elsewhere.
    return db

class BaseModel(pw.Model):
    """
    base model for all tables
    """
    # You don't need to put the databae here,
    # As it's going to get dynamically bound

    # Keeping the base class so there is a place
    # for future shared data.
    # class Meta:
    #     database = get_database()

class User(BaseModel):
    """
    table with user information
    """
    # note that with SQLlite, max_length is not enforced
    user_id = pw.CharField(primary_key=True, max_length=30)
    user_name = pw.CharField(max_length=30)