import os
from setuptools import setup

# Utility function to read the README file.
# Used for the long_description.  It's nice, because now 1) we have a top level
# README file and 2) it's easier to type in the README file than to put a raw
# string in below ...
def read(fname):
    return open(os.path.join(os.path.dirname(__file__), fname)).read()

setup(
    name = "chemplotlib",
    version = "0.0.1",
    author = "Aaron Abbott",
    author_email = "aabmass@gmail.com",
    description = ("An demonstration of how to create, document, and publish "
                                   "to the cheese shop a5 pypi.org."),
    license = "BSD",
    keywords = "chemistry spectra",
    # url = "http://packages.python.org/an_example_pypi_project",
    long_description=read('README'),
    classifiers=[
        "Development Status :: 3 - Alpha",
        "Topic :: Utilities",
        "License :: OSI Approved :: BSD License",
    ],

    packages=['chemplotlib'],
    entry_points = {
        'gui_scripts': ['plot_ocean_optics=chemplotlib.plot_ocean_optics:main'],
    },
)


for t in range(1, int(input())+1):
    M, N = map(int, input().split())
    cnt = 0
    if M == 1 or N == 0:
        cnt = M
    elif M <= N:
        cnt = M*2
    elif M > N and M <= 2:
        cnt = M*2
    elif M > N and N == 1:
        cnt = M+N
    else:
        cnt = M

    print("#{} {}".format(t, cnt))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
    Dado um número inteiro positivo n e uma sequência de n números
    inteiros, determinar a soma dos números inteiros positivos da
    sequência.
        Exemplo:
        Se n = 7 e a sequência é 6; -2; 7; 0; -5; 8; 4, a saída deve ser
        25.
    Faça ao menos uma simulação passo a passo da execução de
    sua solução.
"""
n = int(input('Informe n: ')) # variaveis são indepentendes. o n de dentro da função, é uma variavel local a função, a modificação será para esta variavel.
soma = 0
cont = 0

while cont < n: # é a quantidade de vezes que eu vou contar (somar)
    sequencia = int(input('Informe um digito da sequencia a ser somada: '))

    if sequencia > 0:
        soma = soma + sequencia
    cont += 1
print('A soma dos inteiros informados na sequencia é %d' %(soma))

exit(0)


# put your python code here
sum_all = 0
sum_squares = 0

while True:
    i = int(input())
    sum_all += i
    sum_squares += i ** 2
    if sum_all == 0:
        break

print(sum_squares)


def isoelectric_point(freq, converge_thres)	:  ###based on An algorithm for isoelectric point estimation David L. Tabb
                                ###and the bisection method for finding 0s, similar to python SeqUtils
    ph = 0.0
    #find the limits
    lowerph = 0.0
    while (charge_at_PH(freq,ph) > 0.0):
        lowerph=ph
        ph+=1.0
        # print(f"updating pH: {ph}")
    #print (str(lowerph) + "is the lower limit on iso point")
    upperph = 1.0 + lowerph
    # print(f"updating pH: {ph}")
    #refine the value using bisection
    while (upperph - lowerph > converge_thres):
        ph = (upperph+ lowerph)/2.0
        # print(f"updating pH: {ph}")
        ch=charge_at_PH(freq,float(ph))
        if (ch > 0.0):
            lowerph=ph
        else:
            upperph=ph

    return ph

def charge_at_PH(freq,ph):
    # t = time()
    ch = 0.0
    pKaapos={ 'K': 10.0, 'R': 12.0, 'H': 5.98, }
    pKaaneg={ 'D': 4.05, 'E': 4.45, 'C': 9.0, 'Y': 10.0  }
    pKN = 7.5
    pKC = 3.55
    cr = 10**(pKN-ph)
    ch +=  cr/(cr + 1.0)
    for aa in pKaapos.keys():
        cr = 10**(pKaapos[aa]-ph)
        ch += freq[aa]*cr/(cr + 1.0)
    cr = 10**(ph-pKC)
    ch -=  cr/(cr + 1.0)
    for aa in pKaaneg.keys():
        cr = 10**(ph-pKaaneg[aa])
        ch -= freq[aa]*cr/(cr + 1.0)
    # print("time", time() - t)
    return ch


from aiogram import types

from data.db_models import Chat
from filters import GroupFilter
from loader import Game, dp, db

@dp.message_handler(GroupFilter(),
                    content_types=[types.ContentType.NEW_CHAT_MEMBERS])
async def new_member(message: types.Message):
    members_list = message.new_chat_members
    for user in members_list:
        if user.id == (await dp.bot.get_me()).id:
            await message.answer('Привет🤘! Я бот-ведущий игры мафия🤵🏻 с элементами Brawl Stars!\n'
                                 '⚠ Для адекватной работы мне остро необходимы права администратора!\n'
                                 'Дополнительную информацию можно найти по команде /help в личных сообщениях со мной!')
        else:
            chat_data: Chat = await db.get_chat(message.chat.id)
            if not chat_data.is_show_hello_msg:
                return
            chat_obj = Game.get_chat(message.chat.id)
            if chat_obj:
                if chat_obj.phase in ['day', 'night']:
                    await message.answer(f"💬 {user.get_mention()}, добро пожаловать!"
                                         f"\nВ данный момент идет игра, вам нужно подождать 🕗, "
                                         f"пока она закончится! "
                                         f"А пока вы можете ознакомиться с ℹ правилами игры: /help")
                elif chat_obj.phase == 'starting':
                    await message.answer(f"💬 {user.get_mention()}, добро пожаловать!\n"
                                         f"В данный момент идет подбор игроков, вы можете 🎭 присоединиться!")
            else:
                await message.answer(f"💬 {user.get_mention()}, добро пожаловать!\n"
                                     f"В данный момент не идет игры, "
                                     f"вы можете ознакомиться с ℹ правилами игры: /help.")

@dp.message_handler(content_types=[types.ContentType.GROUP_CHAT_CREATED])
async def group_created(message: types.Message):
    await message.answer('Привет🤘! Я бот-ведущий игры мафия🤵🏻 с элементами Brawl Stars!\n'
                         '⚠ Для адекватной работы мне остро необходимы права администратора!\n'
                         'Дополнительную информацию можно найти по команде /help в личных сообщениях со мной!')


#import json to manipualte the json file format the course data was provided in
import json
from cs50 import SQL

db = SQL("sqlite:///interests.db")

# Open the courses2.json file using json.load to convert the data into a python dictionary
# Used https://stackabuse.com/reading-and-writing-json-to-a-file-in-python/ for reference #
with open('courses2.json', 'r', encoding='utf-8') as data_file:
    data = json.load(data_file)

    # Iterate through each row in the data and write the subject and course number in a SQL database
    for p in range(len(data)):
        db.execute("INSERT INTO realclasses (subject, number) VALUES(:subject,:number)", subject=data[p]["classes"][0]["catalogSubject"], number=data[p]["classes"][0]["courseNumber"])


import numpy as np
from os import makedirs, path

# paths related to the datasets
root = path.expanduser("~") + "/Dropbox/my_files/research/ISR/"
original_datasets_path = root + "datasets/original/"
normalized_datasets_path = root + "datasets/normalized/"

# The "ppb" dataset contains attributes for which all instances have value 0, which means that these attributes have a
# range value that also equals to zero, which in turn causes problems during the normalization. In order to work around
# this problem, these attributes were removed and the dataset was saved as "ppb-wth0s"
# (script "rm_empty_columns_from_ppb.py"). That means that there are two versions of the dataset. All methods that take
# the normalized dataset as input or perform a normalization step must use the modified version.
datasets = ["airfoil", "ccn", "ccun", "concrete", "energyCooling", "energyHeating", "keijzer-6", "keijzer-7",
            "parkinsons", "ppb-wth0s", "towerData", "vladislavleva-1", "wineRed", "wineWhite", "yacht"]

def main():
    if not path.exists(normalized_datasets_path):
        makedirs(normalized_datasets_path)

    for dataset in datasets:
        print("Dataset: " + dataset)

        for fold_id in range(5):
            print("  Fold id: " + str(fold_id))

            tr_file_name = dataset + "-train-" + str(fold_id) + ".csv"
            ts_file_name = dataset + "-test-" + str(fold_id) + ".csv"

            # break the loop if the number of folds is smaller than five
            if not path.isfile(original_datasets_path + tr_file_name):
                break

            # load the data
            tr_data = np.loadtxt(original_datasets_path + tr_file_name, delimiter=",")
            ts_data = np.loadtxt(original_datasets_path + ts_file_name, delimiter=",")

            num_inst_tr = tr_data.shape[0]
            num_inst_ts = ts_data.shape[0]
            num_attr = tr_data.shape[1]

            # Go through each attribute, first checking the minimum value and the range and then overwriting all the
            # values for their respective normalized values.
            for attr_id in range(num_attr):
                # training and test values of the current attribute
                tr_attr_values = tr_data[:, attr_id]
                ts_attr_values = ts_data[:, attr_id]

                # Important: both training and test sets will be normalized based on the minimum value and the range of
                # the training set only, since, as a general rule, this kind of information is unknown for the test set
                # at this time (a pre-processing step).
                attr_min = tr_attr_values.min()
                attr_range = tr_attr_values.max() - attr_min

                normalize_values(tr_data, tr_attr_values, attr_min, attr_range, attr_id, num_inst_tr)
                normalize_values(ts_data, ts_attr_values, attr_min, attr_range, attr_id, num_inst_ts)

            save_values(tr_file_name, tr_data, num_inst_tr, num_attr)
            save_values(ts_file_name, ts_data, num_inst_ts, num_attr)

# Normalize the values of a specific attribute.
def normalize_values(data, attr_values, attr_min, attr_range, attr_id, num_inst):
    for i in range(num_inst):
        value = attr_values[i]
        data[i, attr_id] = (value - attr_min) / attr_range

# Drop the trailing zeros and write the values in the output file.
def save_values(file_name, data, num_rows, num_cols):
    out_file = open(normalized_datasets_path + file_name, "w")

    for i in range(num_rows):
        for j in range(num_cols):
            value = (str(data[i, j]))
            out_file.write(value.rstrip('0').rstrip('.') if '.' in value else value)

            if j != num_cols - 1:
                out_file.write(",")

        out_file.write("\n")

if __name__ == "__main__":
    main()
    print("Done.")


"""
Polarion:
    casecomponent: WebConsole
    linkedWorkItems: MTA_Web_Console
"""
import pytest

from mta.base.application.implementations.web_ui import navigate_to
from mta.entities.analysis_results import AnalysisResults
from mta.entities.analysis_results import AnalysisResultsView
from mta.entities.global_config.rules_configuration import CustomRulesConfiguration
from mta.entities.global_config.rules_configuration import CustomRulesView
from mta.entities.global_config.rules_configuration import SystemRulesConfiguration
from mta.entities.report import AllApplicationsView
from mta.entities.report import Issues

@pytest.fixture(scope="function")
def add_global_custom_rule(mta_app):
    """This fixture with upload global custom rule file"""
    file_name = "custom.Test1rules.rhamt.xml"
    rules_configurations = CustomRulesConfiguration(mta_app, file_name)
    rules_configurations.upload_custom_rule_file()
    view = rules_configurations.create_view(CustomRulesView)
    view.wait_displayed("20s")
    yield file_name, view, rules_configurations
    rules_configurations.delete_custom_rule()
    view.logout()

def test_crud_global_custom_rule(mta_app, add_global_custom_rule):
    """Test to upload global custom rules file

    Polarion:
        assignee: ghubale
        initialEstimate: 1/12h
        caseimportance: medium
        testSteps:
            1. Login to MTA web console
            2. Navigate to Global > Rules configuration > Custom rules
            3. Click on Add rule button and browse rules file
            4. Click on Close button
        expectedResults:
            1. Custom rules file should be listed in table
    """
    file_name, view, rules_configurations = add_global_custom_rule
    assert file_name in [rules["Short path"] for rules in view.table.read()]

def test_search_global_custom_rule(mta_app, add_global_custom_rule):
    """Test to search global custom rules file from table

    Polarion:
        assignee: ghubale
        initialEstimate: 1/12h
        caseimportance: medium
        testSteps:
            1. Login to MTA web console
            2. Navigate to Global > Rules configuration > Custom rules
            3. Click on Add rule button and browse rules files
            4. Click on Close button
            5. Add value in 'Filter by short path' input box and hit enter
        expectedResults:
            1. Custom rules file should searched by substring
    """
    file_name, view, rules_configurations = add_global_custom_rule
    view.wait_displayed("20s")

    view.search.fill("rhamt")
    view.wait_displayed("20s")
    view.search.fill("rhamt-invalid")
    try:
        assert file_name not in [rules["Short path"] for rules in view.table.read()]
        view.search.fill("")
    except IndexError:
        view.search.fill("")
        pass

def test_analysis_global_custom_rule(
    mta_app, add_global_custom_rule, create_minimal_project, request
):
    """Test to upload global custom rules file

    Polarion:
        assignee: ghubale
        initialEstimate: 1/12h
        caseimportance: medium
        testSteps:
            1. Upload global custom rule file
            2. Create project and run analysis
            3. Go to analysis details page and check if custom rules contains global scope custom
               rule file
        expectedResults:
            1. Analysis should be completed successfully
            2. Global custom rule should be applied/fired in the analysis report
    """
    file_name, view, rules_configurations = add_global_custom_rule
    project, project_collection = create_minimal_project
    analysis_results = AnalysisResults(mta_app, project.name)
    view = navigate_to(analysis_results, "AnalysisDetailsPage")
    view.custom_rules.wait_displayed("20s")
    card_info = view.custom_rules.read()
    assert file_name in card_info["body"].split("Global")[1]
    view.execution_link.click()
    view = analysis_results.create_view(AnalysisResultsView)
    view.wait_displayed("30s")
    view.analysis_results.show_report(request)
    view = analysis_results.create_view(AllApplicationsView)
    view.application_table.application_details("acmeair-webapp-1.0-SNAPSHOT.war")
    view.tabs.issues.click()
    view = analysis_results.create_view(Issues)
    # TODO(ghubale): Update test case with reading Migration potential table
    assert view.wait_displayed("20s")

def test_invalid_rule_file_type(mta_app, request):
    """Test to upload global custom rules file

    Polarion:
        assignee: ghubale
        initialEstimate: 1/12h
        caseimportance: medium
        testSteps:
            1. Upload invalid global custom rule file
            2. Check number of rules in it
        expectedResults:
            1. Invalid global custom rule file should have 0 rules
    """
    file_names = ["customWebLogic.windup.label.xml", "empty_rule_file.xml"]

    @request.addfinalizer
    def _finalize():
        for file in file_names:
            rules = CustomRulesConfiguration(mta_app, file)
            rules.delete_custom_rule()
        view.logout()

    for file_name in file_names:
        rules_configurations = CustomRulesConfiguration(mta_app, file_name)
        rules_configurations.upload_custom_rule_file()
        view = rules_configurations.create_view(CustomRulesView)
        view.wait_displayed("5s")

        all_rules = view.table.read()
        for rule in all_rules:
            if rule["Short path"] == file_name:
                assert int(rule["Number of rules"]) == 0

def test_total_global_system_rule(mta_app, request):
    """Test to upload global custom rules file

    Polarion:
        assignee: ghubale
        initialEstimate: 1/12h
        caseimportance: medium
        testSteps:
            1. Navigate to Global > Rules configuration > System rules
            2. Check show all rules
        expectedResults:
            1. Total system rules count should be 331
    """

    @request.addfinalizer
    def _finalize():
        # Reset view else the URL does not change
        view.logout()

    global_configurations = SystemRulesConfiguration(mta_app)
    view = navigate_to(global_configurations, "SystemRule")
    view.show_all_rules.wait_displayed("30s")
    no_of_rules_before = view.paginator.total_items
    view.show_all_rules.click()
    assert view.paginator.total_items >= no_of_rules_before

def test_filter_global_system_rule(mta_app, request):
    """Test to upload global custom rules file

    Polarion:
        assignee: ghubale
        initialEstimate: 1/12h
        caseimportance: medium
        testSteps:
            1. Navigate to Global > Rules configuration > System rules
            2. Check show all rules
        expectedResults:
            1. Total system rules count should be 331
    """
    filters = {
        "Source": ["agroal", "amazon", "avro"],
        # "Target": ["camel", "cloud-readiness", "quarkus"],
        # TODO(ghubale): Uncomment it once fixed drop down selection for option - Target
    }

    @request.addfinalizer
    def _finalize():
        # Reset view else the URL does not change
        view.logout()

    global_configurations = SystemRulesConfiguration(mta_app)
    view = navigate_to(global_configurations, "SystemRule")
    view.show_all_rules.wait_displayed("30s")
    view.show_all_rules.click()
    for filter_type in filters:
        for filter_value in filters[filter_type]:
            global_configurations.search_system_rules(
                search_value=filter_value, filter_type=filter_type, clear_filters=True
            )
            filtered_rules = view.table.read()
            for rule in filtered_rules:
                assert filter_value in rule[filter_type]


from src.data_preparation.pipeline.pipeline import Pipeline
from functools import wraps
from src.data_preparation.pipeline.stock_data.summary import SummaryStockData

class PipelineStockData(Pipeline):

    def __init__(self):
        self.summary = SummaryStockData()
        self._scalers = None
        self._data = None

    @classmethod
    def process(cls, function):

        @wraps(function)
        def process_data(self, *args, show_summary=True, dict_summary=True, **kwargs):

            data, additional_summary_information = function(self, *args, **kwargs)

            if len(data) == 3:
                self._scalers, self._data, initial_index = data
                final_index = initial_index
            else:
                self._scalers, self._data, initial_index, final_index = data

            if not additional_summary_information:
                additional_summary_information = {}

            return self._summary_management(show_summary, dict_summary)\
                (show_summary, dict_summary,
                 priority = self.priority,
                 initial_index=initial_index,
                 final_index=final_index,
                 scaler=self._scalers,
                 transform_functions=function.__doc__,
                 **additional_summary_information)

        return process_data

    @property
    def data(self):
        return self._data

    @property
    def scalers(self):
        return self._scalers

    def _write_summary(self, **kwargs):
        self.summary.enter_params(**kwargs)
        self.summary.build()

    def _summary_management(self, show_summary, dict_summary):

        if show_summary or dict_summary:
            return self._summary_actions
        return lambda *args, **kwargs: None

    def _summary_actions(self, show_summary, dict_summary, **kwargs):

        self._write_summary(**kwargs)
        if show_summary:
            print(self.summary.str_summary)
        if dict_summary:
            return self.summary.registry
        return None


# 题目：给定一个二叉树, 找到该树中两个指定节点的最近公共祖先（一个节点也可以是它自己的祖先）
# https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/solution/236-er-cha-shu-de-zui-jin-gong-gong-zu-xian-hou-xu/
# 思路： 先理解定义，有两种情况：1. p,q 皆为子树节点 2.p,q其中一个为上级节点
# 利用回溯从底向上搜索，遇到一个节点的左子树里有p，右子树里有q，那么当前节点就是最近公共祖先。

# 最佳解法； 递归法 回溯
class Solution:
    # 1.确定函数返回值与入参
    # 需要递归函数返回值，来告诉我们是否找到节点q或者p,如果找到就返回根节点，没找到就返回None
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        # 2.确定递归停止条件
        if not root:
            return root
        # 如果找到了p,q 其中一个是根节点，就返回该节点
        if root == q or root == p:
            return root

        # 3.确定单层递归逻辑
        # 在左子树找,由于p,q值不同，所以不会找重复的
        left = self.lowestCommonAncestor(root.left, p, q)
        # 在右子树找
        right = self.lowestCommonAncestor(root.right, p, q)
        # 分情况讨论
        # p,q分别在左右子树上:left,right 均有值,那么公共祖先就是当前节点了
        if left and right:
            return root
        # q,p 在同一子树上：这里也分两种情况，谁在前后
        elif left and not right:
            return left
        elif not left and right:
            return right
        # 最后一种情况就是未找到(当然本题给的条件时必然存在)
        else:
            return None

236. 二叉树的最近公共祖先.py


# going to use the in range loop

def square_num(n):
    for i in range(0,n):
        my_square = i*i
        my_output = "{} squared = {}".format(i,my_square)
        print(my_output)
    print()

#square_num(20)
#square_num(1000)

def cube_num(n):
    for i in range(0,n):
        my_cube = i*i*i
        my_output = "{} cubed = {}".format(i,my_cube)
        print(my_output)
    print()

#cube_num(15)

def menu():
    # putting menu into a loop
    # define a variable to stop or start the loop (run is this variable)
    run = True
    while run == True:
        my_menu = '''
                    A: Square Numbers
                    B: Cube Numbers
                    Q: Quit
                    '''
        print("Welcome!")
        print(my_menu)
        choice = input("Please choose an option")
        if choice == "A":
            square_num(6)
        elif choice == "B":
            cube_num(11)
        elif choice == "Q":
            # leaving the loop when you want to quit
            run = False
            print("Thanks for squaring and cubing!")
        else:
            print("Invalid entry")

menu()


__author__ = 'Steve'
# This makes the queue a First-In-First-Out (FIFO) data structure. In a FIFO data structure, the first element added to the queue will be the first one to be removed.
# This is equivalent to the requirement that once a new element is added, all elements that were added before have to be removed before the new element can be removed.

def letter_queue(commands):
    queue = [] #used to store the queue as it is being built
    for command in commands:
        action = command[:2] # first two chars of command uniquely identifies push or pop
        if action == "PU":
            queue.append(command[-1]) #add the last char to the end of the queue
        elif queue != []: # check that the list is not empty
            queue.pop(0) # remove the first element in the list - default value removes the last
        print(queue)
    return "".join(queue) # joining the list 'queue' with an empty string converts the list to a string

if __name__ == '__main__':
    #These "asserts" using only for self-checking and not necessary for auto-testing
    assert letter_queue(["PUSH A", "POP", "POP", "PUSH Z", "PUSH D", "PUSH O", "POP", "PUSH T"]) == "DOT", "dot example"
    assert letter_queue(["POP", "POP"]) == "", "Pop, Pop, empty"
    assert letter_queue(["PUSH H", "PUSH I"]) == "HI", "Hi!"
    assert letter_queue([]) == "", "Nothing"


import time
import grovepi
import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-p", "--pin", required=True,
                                help="GrovePi Pin")
args = vars(ap.parse_args())

pin = int(args['pin'])

while True:
    try:
        value = grovepi.analogRead(pin)
        print("value = {}".format(value))
        time.sleep(.5)

    except IOError:
        print ("Error")


from heapq import heappop, heappush
from utils import get_file_content, parse_as_csv_content
from string import ascii_lowercase

WAITING_ON_STATION = 5
TRAIN_SOURCE = "_"
EVENT_ARRIVE = 1
EVENT_LEAVE = 2
EVENT_STATION_STATE_CHANGE = 3

def transform_time_to_minutes(time_value: str):
    hour, minutes = map(int, time_value.split(":"))
    return hour * 60 + minutes

def transposition(source):
    result = None
    for row in source:
        if result == None:
            result = [[] for _ in row if _ != "a"]

        tmp = enumerate(row)
        next(tmp)
        for index, column in tmp:
            result[index - 1].append(column)

    yield from result

def transform_to_trains_table(content: str):
    for row in transposition(parse_as_csv_content(content)):
        x = [None if t == "" else transform_time_to_minutes(t) for t in row]

        result = {}
        previous_station = TRAIN_SOURCE
        previous_time = 0
        for index, station_time in enumerate(x):
            if station_time == None:
                continue

            station = ascii_lowercase[index]
            result[previous_station] = (station, station_time - previous_time)
            previous_station = station
            previous_time = station_time

        yield result

def solution(content: str) -> int:
    stations_names = set()
    trains = []

    for s in transform_to_trains_table(content):
        trains.append(s)
        stations_names.update(s.keys())
        stations_names.update(x[0] for x in s.values())

    stations_names.remove(TRAIN_SOURCE)
    events = []
    starts_times = {}
    ends_times = {}

    stations_queues = {s: [] for s in stations_names}
    stations = {s: None for s in stations_names}

    for train_index, train in enumerate(trains):
        starts_times[train_index] = train[TRAIN_SOURCE][1]
        heappush(
            events,
            (
                train[TRAIN_SOURCE][1],
                EVENT_ARRIVE,
                train_index,
                train[TRAIN_SOURCE][0],
                TRAIN_SOURCE,
            ),
        )

    while events:
        time, event_type, train_index, current_station, from_station = heappop(events)

        if event_type == EVENT_ARRIVE:
            stations_queues[current_station].append((from_station, time, train_index))
            heappush(
                events,
                (
                    time,
                    EVENT_STATION_STATE_CHANGE,
                    None,
                    current_station,
                    None,
                ),
            )

        elif event_type == EVENT_LEAVE:
            stations[current_station] = None
            heappush(
                events,
                (
                    time,
                    EVENT_STATION_STATE_CHANGE,
                    None,
                    current_station,
                    None,
                ),
            )

            if current_station not in trains[train_index]:
                ends_times[train_index] = time
            else:
                to_state, time_difference = trains[train_index][current_station]
                heappush(
                    events,
                    (
                        time + time_difference,
                        EVENT_ARRIVE,
                        train_index,
                        to_state,
                        current_station,
                    ),
                )

        elif event_type == EVENT_STATION_STATE_CHANGE:
            if stations[current_station] == None and stations_queues[current_station]:
                stations_queues[current_station].sort(reverse=True)
                train_id = stations_queues[current_station].pop()[2]
                stations[current_station] = train_id
                heappush(
                    events,
                    (
                        time + WAITING_ON_STATION,
                        EVENT_LEAVE,
                        train_id,
                        current_station,
                        current_station,
                    ),
                )

    return max(
        ends_times[train_index] - _from for train_index, _from in starts_times.items()
    )

assert (
    solution(
        """station,r1,r2,r3
a,00:01,,00:02
b,00:16,,00:17
c,,00:21,
d,00:46,00:51,00:47"""
    )
    == 64
)

print("Solution", solution(get_file_content("input34.csv")))


import os

from google.appengine.ext.webapp import template

register = template.create_template_register()

def addfilemtime(filepath):
	trimpath = filepath.rstrip('/')
	realpath = os.path.join(os.path.dirname(__file__), '..',
			                'staticsymbol', trimpath.strip('/'))
	mtime = int(os.stat(realpath).st_mtime)
	tmp = trimpath.split('/')
	tmp.insert(-1, str(mtime))
	return '/'.join(tmp)
register.filter(addfilemtime)


from sz.core import utils, models
from sz.core.services.parameters import names as params_names

def get_paging_from_dict(args):
    to_int = lambda name: utils.safe_cast(args.get(name, None), int, None)
    to_none_if_neg_int = lambda v: v and (v > 0 and v or None) or None
    to_pos_int = lambda name: to_none_if_neg_int(to_int(name))
    limit = to_pos_int(params_names.LIMIT)
    offset = to_pos_int(params_names.OFFSET)
    max_id = to_pos_int(params_names.MAX_ID)
    return limit, offset, max_id

def get_position_from_dict(args):
    latitude = args.get(params_names.LATITUDE, None)
    longitude = args.get(params_names.LONGITUDE, None)
    assert latitude and longitude, 'latitude and longitude are required'
    return latitude, longitude

class ParametersGroupBase:

    def __init__(self, params):
        self.params = params

    def get_db_params(self):
        pass

    def get_api_params(self):
        pass

class ParametersGroupDecorator(ParametersGroupBase):

    def __init__(self, params, component=None):
        ParametersGroupBase.__init__(self, params)
        self.__component = component

    def get_db_params(self):
        if self.__component:
            return self.__component.get_db_params()
        else:
            return dict()

    def get_api_params(self):
        if self.__component:
            return self.__component.get_api_params()
        else:
            return dict()

class PositionDecorator(ParametersGroupDecorator):

    def __init__(self, params, component=None):
        ParametersGroupDecorator.__init__(self, params, component)
        self._latitude, self._longitude = get_position_from_dict(self.params)

    def __get_params(self, params):
        params[params_names.LATITUDE] = self._latitude
        params[params_names.LONGITUDE] = self._longitude
        return params

    def get_db_params(self):
        params = ParametersGroupDecorator.get_db_params(self)
        return self.__get_params(params)

    def get_api_params(self):
        params = ParametersGroupDecorator.get_api_params(self)
        return self.__get_params(params)

class LocationDecoratorBase(PositionDecorator):

    def __init__(self, params, city_service, component=None):
        PositionDecorator.__init__(self, params, component)
        self.__city_service = city_service
        self._radius = utils.safe_cast(params.get(params_names.RADIUS, None), int, None)
        if self._radius is not None:
            if self._radius <= 0:
                self._radius = None

    def _get_city(self):
        city = self.__city_service.get_city_by_position(self._longitude, self._latitude)
        return city

    def get_api_params(self):
        params = PositionDecorator.get_api_params(self)
        if self._radius is not None:
            params[params_names.RADIUS] = self._radius
        return params

class LocationDecorator(LocationDecoratorBase):

    def get_db_params(self):
        params = LocationDecoratorBase.get_db_params(self)
        params[params_names.RADIUS] = self._radius
        if self._radius is None:
            city = self._get_city()
            params[params_names.CITY_ID] = city['id']
        return params

class LocationAlwaysWithCityDecorator(LocationDecoratorBase):

    def get_db_params(self):
        params = LocationDecoratorBase.get_db_params(self)
        params[params_names.RADIUS] = self._radius
        city = self._get_city()
        params[params_names.CITY_ID] = city['id']
        return params

class PagingDecorator(ParametersGroupDecorator):

    def __init__(self, params, current_max_id, default_limit, component=None):
        ParametersGroupDecorator.__init__(self, params, component)
        self.__limit, self.__offset, self.__max_id = get_paging_from_dict(self.params)
        self.__current_max_id = current_max_id
        self.__default_limit = default_limit

    def __get_params(self, params):
        params[params_names.MAX_ID] = self.__max_id or self.__current_max_id
        params[params_names.LIMIT] = self.__limit or self.__default_limit
        params[params_names.OFFSET] = self.__offset or 0
        return params

    def get_db_params(self):
        params = ParametersGroupDecorator.get_db_params(self)
        return self.__get_params(params)

    def get_api_params(self):
        params = ParametersGroupDecorator.get_api_params(self)
        return self.__get_params(params)

class ContentDecorator(ParametersGroupDecorator):

    def __init__(self, params, categorization_service, component=None):
        ParametersGroupDecorator.__init__(self, params, component)
        self.__categorization_service = categorization_service
        self.__category = params.get(params_names.CATEGORY, None)
        self.__query = params.get(params_names.QUERY, None)
        self.__photo = params.get(params_names.PHOTO, None)

    def get_db_params(self):
        params = ParametersGroupDecorator.get_db_params(self)
        params[params_names.STEMS] = []
        if self.__query:
            if self.__query.strip != '':
                params[params_names.STEMS] = self.__categorization_service.detect_stems(self.__query)
        if isinstance(self.__category, models.Category):
            params[params_names.CATEGORY] = self.__category
        else:
            params[params_names.CATEGORY] = None
        if self.__photo:
            params[params_names.PHOTO] = True
        else:
            params[params_names.PHOTO] = None
        return params

    def get_api_params(self):
        params = ParametersGroupDecorator.get_api_params(self)
        if self.__query:
            if self.__query.strip != '':
                params[params_names.QUERY] = self.__query
        if isinstance(self.__category, models.Category):
            params[params_names.CATEGORY] = self.__category
        else:
            params[params_names.CATEGORY] = None
        if self.__photo:
            params[params_names.PHOTO] = True
        return params

class PlaceNameDecorator(ParametersGroupDecorator):

    def __init__(self, params, component=None):
        ParametersGroupDecorator.__init__(self, params, component)
        self.__query = params.get(params_names.QUERY, None)

    def get_db_params(self):
        params = ParametersGroupDecorator.get_db_params(self)
        params[params_names.QUERY] = self.__query
        return params

    def get_api_params(self):
        params = ParametersGroupDecorator.get_api_params(self)
        params[params_names.QUERY] = self.__query
        return params

class PlaceMessagesParametersFactory:

    @classmethod
    def create(cls, params, categorization_service, current_max_id, default_limit):
        content_group = ContentDecorator(params, categorization_service)
        paging_group = PagingDecorator(params, current_max_id, default_limit, content_group)
        return paging_group

class PlaceNewsParametersFactory:

    @classmethod
    def create(cls, params, categorization_service, current_max_id, default_limit):
        content_group = ContentDecorator(params, categorization_service)
        position_group = PositionDecorator(params, content_group)
        paging_group = PagingDecorator(params, current_max_id, default_limit, position_group)
        return paging_group

class NewsParametersFactory:

    @classmethod
    def create(cls, params, categorization_service, city_service, current_max_id, default_limit):
        content_group = ContentDecorator(params, categorization_service)
        location_group = LocationDecorator(params, city_service, content_group)
        paging_group = PagingDecorator(params, current_max_id, default_limit, location_group)
        return paging_group

class PlaceSearchParametersFactory:

    @classmethod
    def create(cls, params, city_service):
        location_group = LocationAlwaysWithCityDecorator(params, city_service)
        place_name_group = PlaceNameDecorator(params, location_group)
        return place_name_group


from ursina import *
from ursina.shaders import lit_with_shadows_shader
from ursina.lights import DirectionalLight

from simulators.ursina.ursina_mesh import create_sphere

shader = lit_with_shadows_shader
shader.default_input = {
    'texture_scale': Vec2(1, 1),
    'texture_offset': Vec2(0, 0),
    'shadow_color': Vec4(0.1, 0.1, 0.1, .5),
}

Entity.default_shader = shader

app = Ursina()

moon = Entity(model=create_sphere(0.5, 32), texture="../textures/moon.png", y=1, color=color.light_gray)
earth = Entity(model=create_sphere(0.5, 32), texture='../textures/earth.png', y=1, x=1, z=3)
e_pos = earth.position

sun = DirectionalLight(shadow_map_resolution=(1024, 1024), position=[e_pos[0], e_pos[1] + 1, e_pos[2] + 1])
sun.look_at(moon)
sun._light.show_frustum()

# light = PointLight(parent=earth, intensity=10, range=10, color=color.white)

def update():
    moon.x += (held_keys['d'] - held_keys['a']) * time.dt
    moon.y += (held_keys['e'] - held_keys['q']) * time.dt
    moon.z += (held_keys['w'] - held_keys['s']) * time.dt
    sun.update_bounds()

# scene.fog_density = (100, 500)
# scene.fog_color = color.orange
# scene.fog_density = (10, 50)
Sky(color=color.light_gray, texture="../textures/cosmic1.png")
EditorCamera()

app.run()


import datetime

from commercetools.importapi import models

def test_serialization_optional_values():
    item = models.LineItemImportDraft(
        name={"nl-NL": "foobar"},
        variant=models.LineItemProductVariantImportDraft(sku="foobar"),
        price=models.LineItemPrice(
            value=models.Money(cent_amount=1000, currency_code="EUR"),
        ),
        quantity=3,
    )

    data = item.serialize()
    item_cycle = models.LineItemImportDraft.deserialize(data)
    data_cycle = item_cycle.serialize()

    expected = {
        "name": {"nl-NL": "foobar"},
        "price": {
            "value": {
                "centAmount": 1000,
                "currencyCode": "EUR",
                "type": "centPrecision",
            }
        },
        "quantity": 3.0,
        "variant": {"sku": "foobar"},
    }
    assert expected == data
    assert expected == data_cycle

def test_serialization_optional_values():
    now = datetime.datetime(2021, 1, 30, 11, 21, 8)
    custom = models.Custom(
        type=models.TypeKeyReference(key="my-custom-type"),
        fields=models.FieldContainer(
            {
                "foo": models.NumberField(value=1234),
                "itemDate": models.DateTimeField(value=now),
            }
        ),
    )
    data = custom.serialize()
    expected = {
        "fields": {
            "foo": {
                "type": "Number",
                "value": 1234,
            },
            "itemDate": {
                "type": "DateTime",
                "value": "2021-01-30T11:21:08",
            },
        },
        "type": {"typeId": "type", "key": "my-custom-type"},
    }
    assert data == expected


import math

# explain the choices to the user
print("Choose either 'investment' or 'bond' from the menu below to proceed: ")
print("")
print("investment   - to calculate the amount of interest you'll earn on your investment")
print("bond         - to calculate the amount you'll have to pay on a home loan")
print("")

# user inputs choice
selection = input("Investment or Bond: ")

option_1 = 'investment'
option_2 = 'bond'

# if 'investment' is selected
if selection.lower() == option_1.lower():
    deposit = float(input("Amount depositing: "))
    interest_rate = float(input("Interest rate: "))
    years = int(input("Number of years to invest: "))
    interest = input("'Simple' or 'Compound' interest? ")

# SIMPLE or COMPOUND
    option_a = 'simple'
    option_b = 'compound'

# if simple
    if interest.lower() == option_a.lower():
        total_amount = deposit*(1+(interest_rate/100)*years)
        print(f"The amount after {years} years is £{round(total_amount, 2)}")
# if compound
    elif interest.lower() == option_b.lower():
        total_amount = deposit*math.pow((1+(interest_rate/100)),years)
        print(f"The amount after {years} years is £{round(total_amount, 2)}")
    else:
        print("Invalid type of interest selected.")

# if 'bond' is selected
elif selection.lower() == option_2.lower():
    value = float(input("Present value of your house: "))
    interest_rate = float(input("Interest rate: "))
    months = int(input("Number of months to repay: "))
    monthly_interest = (interest_rate/100)/12

# amount to repay per month
    repay_amount = ((monthly_interest)*value)/(1-(1+(monthly_interest))**(-months))
    print(f"The repayment per month is £{round(repay_amount, 2)}")

# if input is invalid
else:
    print("An error has occurred.")
    print("Please choose either 'investment' or 'bond'.")


from ase import units
from ase.md.langevin import Langevin
from pyiron_base import GenericParameters
from pyiron.gpaw.pyiron_ase import AseAdapter
from pyiron.atomistics.job.interactivewrapper import InteractiveWrapper

__author__ = "Jan Janssen"
__copyright__ = (
    "Copyright 2020, Max-Planck-Institut für Eisenforschung GmbH - "
    "Computational Materials Design (CM) Department"
)
__version__ = "1.0"
__maintainer__ = "Jan Janssen"
__email__ = "janssen@mpie.de"
__status__ = "development"
__date__ = "Sep 1, 2018"

class LangevinAse(InteractiveWrapper):
    """
    Reference implementation of a thermostat implemented in ASE. While we have multiple implementations of the
    Langevin thermostat already, this one is using the ASE interface and the Langevin thermostat implemented in ASE.
    It is therefore a perfect example how other thermostats implemented in ASE can be used inside pyiron.

    Args:
        project (ProjectHDFio): points to the HDF5 file the job is stored in
        job_name (str): name of the job, which has to be unique within the project

    Attributes:
        input (pyiron.objects.hamilton.md.lammps.Input): handle the input
    """

    def __init__(self, project, job_name):
        super(LangevinAse, self).__init__(project, job_name)
        self.__name__ = "LangevinAse"
        self.input = Input()
        self._fast_mode = False

    def set_input_to_read_only(self):
        """
        This function enforces read-only mode for the input classes, but it has to be implement in the individual
        classes.
        """
        super(LangevinAse, self).set_input_to_read_only()
        self.input.read_only = True

    def write_input(self):
        """
        No input is written when using the ASE interface
        """
        pass

    def _write_run_wrapper(self, debug=False):
        """
        No wrapper is written for the ASE interface

        Args:
            debug (bool): the debug flag is ignored
        """
        pass

    def run_static(self):
        """
        Static run function, which uses the ASEAdapter to connect the pyiron interactive reference job with the
        Langevin thermostat implemented in ASE, by setting the ASEAdapter as a replacement of the ASE atoms object.
        """
        self.status.running = True
        self.ref_job_initialize()
        aseadapter = AseAdapter(self.ref_job, self._fast_mode)
        langevin = Langevin(
            atoms=aseadapter,
            timestep=self.input["time_step"] * units.fs,
            temperature=self.input["temperature"] * units.kB,
            friction=self.input["friction"],
            fixcm=True,
        )
        langevin.run(self.input["ionic_steps"])
        self.status.collect = True
        aseadapter.interactive_close()
        self._finish_job()

class Input(GenericParameters):
    """
    class to control the generic input for a Sphinx calculation.

    Args:
        input_file_name (str): name of the input file
        table_name (str): name of the GenericParameters table
    """

    def __init__(self, input_file_name=None, table_name="input"):
        super(Input, self).__init__(
            input_file_name=input_file_name,
            table_name=table_name,
            comment_char="#",
            separator_char="=",
            end_value_char=";",
        )

    def load_default(self):
        """
        Loads the default file content
        """
        file_content = (
            "ionic_steps = 100\n"
            "temperature = 1500\n"
            "time_step = 1\n"
            "friction = 0.002\n"
            "fix_center_of_mass = True\n"
        )
        self.load_string(file_content)


import statistics
from math import log2

class Attribute:
    def __init__(self, name, values, is_label, is_numeric, median):
        self.attribute_name = name
        self.in_attributes = True
        self.values = values
        self.is_label = is_label
        self.is_numeric = is_numeric
        self.median = median

    def __str__(self):
        return 'name:' + Attribute.printable(self.attribute_name)

    @staticmethod
    def printable(thing):
        return thing + '\n'

class Node:

    count = 0

    def __init__(self, value, is_leaf):
        self.value = value
        self.children = {}
        self.is_leaf = is_leaf

    @staticmethod
    def check_error(tree, examples, attributes):
        correct_count = 0
        for example in examples:
            label_from_tree = tree.travel_tree(example, attributes)
            if label_from_tree == example[-1]:
                correct_count += 1
        return correct_count/len(examples) * 100

    def travel_tree(self, example, attributes):
        if self.is_leaf:
            return self.value
        attr_split = self.value
        index, values = Node.find_attribute_values(attr_split, attributes)
        value = example[index]
        if attributes[index].is_numeric:
            if value <= attributes[index].median:
                return self.children['le'].travel_tree(example, attributes)
            else:
                return self.children['g'].travel_tree(example, attributes)
        else:
            return self.children[value].travel_tree(example, attributes)

    @staticmethod
    def same_label(examples):  # check if all labels are the same
        first_label = examples[0][-1]
        for example in examples[1:]:
            if example[-1] != first_label:
                return False, ''
        return True, first_label

    @staticmethod
    def get_majority_label(examples, attributes):
        label = attributes[-1]
        label_values = {}
        for value in label.values:
            label_values[value] = 0
        majority_label = label.values[0]
        majority_label_count = 0
        for example in examples:
            label = example[-1]
            label_values[label] += 1
            if label_values[label] > majority_label_count:
                majority_label_count = label_values[label]
                majority_label = label
        return majority_label

    @staticmethod
    def decision_stump(examples, attributes, info_gain):
        return Node.id3(examples, attributes, info_gain, 0, 1)

    @staticmethod
    def id3(examples, attributes, info_gain, current_depth, max_depth):
        if max_depth == current_depth or Node.attributes_empty(attributes):
            value = Node.get_majority_label(examples, attributes)
            return Node(value, True)
        is_same_label, value = Node.same_label(examples)
        if is_same_label:
            return Node(value, True)
        else:
            attribute_split = info_gain(examples, attributes)
            new_root = Node(attribute_split, False)
            attribute_index, attribute_values = Node.find_attribute_values(attribute_split, attributes)
            for value in attribute_values:
                subset = Node.find_subset_examples(value, attribute_index, examples, attributes)
                if len(subset) == 0:
                    new_value = Node.get_majority_label(examples, attributes)
                    new_root.children[value] = Node(new_value, True)
                else:
                    attributes[attribute_index].in_attributes = False
                    new_root.children[value] = Node.id3(subset, attributes, info_gain, current_depth+1, max_depth)
                    attributes[attribute_index].in_attributes = True
            return new_root

    @staticmethod
    def find_label(attributes):
        for attribute in attributes:
            if attribute.is_label:
                return attribute

    @staticmethod
    def find_attribute_values(attribute_name, attributes):
        Node.count += 1
        # print(Node.count)
        for i, attribute in enumerate(attributes):
            if attribute.attribute_name == attribute_name and attribute.in_attributes:
                return i, attribute.values

    @staticmethod
    def find_subset_examples(attribute_value, index, examples, attributes):
        new_subset = []
        for example in examples:
            if attributes[index].is_numeric:
                if attribute_value == 'le' and example[index] <= attributes[index].median:
                    new_subset.append(example)
                elif attribute_value == 'g' and example[index] > attributes[index].median:
                    new_subset.append(example)
            elif example[index] == attribute_value:
                new_subset.append(example)
        return new_subset

    @staticmethod
    def reclaim_attributes(attributes):
        for attribute in attributes:
            attribute.in_attributes = True

    @staticmethod
    def attributes_empty(attributes):
        for attribute in attributes:
            if attribute.in_attributes and not attribute.is_label:
                return False
        return True

    @staticmethod
    def open_data(filename):
        examples = []  # represents our set of examples
        with open(filename) as data:
            for example in data:
                example = example.replace('\n', '').split(
                    ',')  # replace each end line with an empty string and then split
                examples.append(example)  # add to set of examples
        return examples

    @staticmethod
    def create_attributes(names, vals_to_create, attr_training_examples, attr_test_examples):
        attributes_to_create = []
        for create_index, name in enumerate(names):
            if vals_to_create[create_index] == 'numeric':
                attribute_vals = []
                for example in attr_training_examples:
                    example[create_index] = int(example[create_index])
                    attribute_vals.append(example[create_index])
                median = statistics.median(attribute_vals)
                for example in attr_test_examples:
                    example[create_index] = int(example[create_index])
                new_attribute = Attribute(name, ['le', 'g'], False, True, median)
                attributes_to_create.append(new_attribute)
            else:
                new_attribute = Attribute(name, vals_to_create[create_index], False, False, -1)
                attributes_to_create.append(new_attribute)
        attributes_to_create[-1].is_label = True
        return attributes_to_create

    @staticmethod
    def replace_unknowns(unk_training_examples, unk_test_examples, unk_attributes):
        for unknown_index, attribute in enumerate(unk_attributes):
            if 'unknown' in attribute.values:
                values_count = dict.fromkeys(attribute.values, 0)
                del values_count['unknown']
                max_count = 0
                max_label = unk_training_examples[0][unknown_index]
                for example in unk_training_examples:
                    if example[unknown_index] != 'unknown':
                        values_count[example[unknown_index]] += 1
                        if values_count[example[unknown_index]] > max_count:
                            max_label = example[unknown_index]
                for example in unk_training_examples:
                    if example[unknown_index] == 'unknown':
                        example[unknown_index] = max_label
                for example in unk_test_examples:
                    if example[unknown_index] == 'unknown':
                        example[unknown_index] = max_label

    @staticmethod
    def info_gain(examples, ig_attributes):
        label = Node.find_label(ig_attributes)  # label attribute object
        numb_examples = len(examples)  # number of examples
        entropy_s = 0
        for value in label.values:
            label_count = 0
            for example in examples:
                if example[-1] == value:
                    label_count += 1
            p = label_count / numb_examples
            if p != 0:
                entropy_s += (-p * log2(p))
        greatest_gain = 0
        greatest_gain_name = ig_attributes[0].attribute_name
        for ig_i, attribute in enumerate(ig_attributes):
            if not attribute.is_label and attribute.in_attributes:
                expected_entropy = 0
                if attribute.is_numeric:
                    values_numeric = {'g': 0, 'le': 0}
                    label_values_numeric = dict.fromkeys(label.values, 0)
                    for example in examples:
                        if example[ig_i] <= attribute.median:
                            values_numeric['le'] += 1
                            label_values_numeric[example[-1]] += 1
                    entropy_value_numeric = 0
                    if values_numeric['le'] != 0:
                        for label_value in label_values_numeric:
                            p = label_values_numeric[label_value] / values_numeric['le']
                            if p != 0:
                                entropy_value_numeric += (-p * log2(p))
                        expected_entropy += ((values_numeric['le'] / len(examples)) * entropy_value_numeric)
                    label_values_numeric = dict.fromkeys(label.values, 0)
                    for example in examples:
                        if example[ig_i] > attribute.median:
                            values_numeric['g'] += 1
                            label_values_numeric[example[-1]] += 1
                    entropy_value_numeric = 0
                    if values_numeric['g'] != 0:
                        for label_value in label_values_numeric:
                            p = label_values_numeric[label_value] / values_numeric['g']
                            if p != 0:
                                entropy_value_numeric += (-p * log2(p))
                        expected_entropy += ((values_numeric['g'] / len(examples)) * entropy_value_numeric)
                else:
                    for value in attribute.values:
                        label_values = dict.fromkeys(label.values, 0)
                        value_count = 0
                        for example in examples:
                            if example[ig_i] == value:
                                value_count += 1
                                label_values[example[-1]] += 1
                        proportion_value = value_count / numb_examples
                        entropy_value = 0
                        if value_count != 0:
                            for label_value in label_values:
                                p = label_values[label_value] / value_count
                                if p != 0:
                                    entropy_value += (-p * log2(p))
                            expected_entropy += (proportion_value * entropy_value)
                gain = entropy_s - expected_entropy
                if gain >= greatest_gain:
                    greatest_gain = gain
                    greatest_gain_name = attribute.attribute_name
        return greatest_gain_name

    @staticmethod
    def majority_error(examples, me_attributes):
        label = Node.find_label(me_attributes)  # label attribute object
        label_counts = dict.fromkeys(label.values, 0)
        max_count = 0
        max_label = label.values[0]
        for example in examples:
            label_counts[example[-1]] += 1
            if max_count < label_counts[example[-1]]:
                max_count = label_counts[example[-1]]
                max_label = example[-1]
        wrong_count = 0
        for example in examples:
            if example[-1] != max_label:
                wrong_count += 1
        numb_examples = len(examples)  # number of examples
        maj_error_s = wrong_count / numb_examples
        greatest_gain = 0
        greatest_gain_name = me_attributes[0].attribute_name
        for me_i, attribute in enumerate(me_attributes):
            if not attribute.is_label and attribute.in_attributes:
                maj_error_val = 0
                if attribute.is_numeric:
                    values_numeric = {'g': 0, 'le': 0}
                    label_values_numeric = dict.fromkeys(label.values, 0)
                    maj_label = label.values[0]
                    maj_count = 0
                    for example in examples:
                        if example[me_i] <= attribute.median:
                            values_numeric['le'] += 1
                            label_values_numeric[example[-1]] += 1
                            if label_values_numeric[example[-1]] > maj_count:
                                maj_count = label_values_numeric[example[-1]]
                                maj_label = example[-1]
                    error_count = 0
                    for numeric_label in label_values_numeric:
                        if numeric_label != maj_label:
                            error_count += label_values_numeric[numeric_label]
                    if label_values_numeric[maj_label] != 0:
                        maj_error_val += ((label_values_numeric[maj_label] / numb_examples) *
                                          (error_count / label_values_numeric[maj_label]))
                    maj_label = label.values[0]
                    maj_count = 0
                    label_values_numeric = dict.fromkeys(label.values, 0)
                    for example in examples:
                        if example[me_i] > attribute.median:
                            values_numeric['g'] += 1
                            label_values_numeric[example[-1]] += 1
                            if label_values_numeric[example[-1]] > maj_count:
                                maj_count = label_values_numeric[example[-1]]
                                maj_label = example[-1]
                    error_count = 0
                    for numeric_label in label_values_numeric:
                        if numeric_label != maj_label:
                            error_count += label_values_numeric[numeric_label]
                    if label_values_numeric[maj_label] != 0:
                        maj_error_val += ((label_values_numeric[maj_label] / numb_examples) *
                                          (error_count / label_values_numeric[maj_label]))
                else:
                    attribute_vals = attribute.values
                    for value in attribute_vals:
                        label_values = dict.fromkeys(label.values, 0)
                        maj_label = label.values[0]
                        maj_label_count = 0
                        for example in examples:
                            if example[me_i] == value:
                                label_values[example[-1]] += 1
                                if label_values[example[-1]] >= maj_label_count:
                                    maj_label_count = label_values[example[-1]]
                                    maj_label = example[-1]
                        error_count = 0
                        for label_value in label_values:
                            if label_value != maj_label:
                                error_count += label_values[label_value]
                        if label_values[maj_label] != 0:
                            maj_error_val += ((label_values[maj_label] / numb_examples) *
                                              (error_count / label_values[maj_label]))
                gain = maj_error_s - maj_error_val
                if gain >= greatest_gain:
                    greatest_gain = gain
                    greatest_gain_name = attribute.attribute_name
        return greatest_gain_name

    @staticmethod
    def gini_index(examples, gini_index_attributes):
        label = Node.find_label(gini_index_attributes)  # label attribute object
        label_counts = dict.fromkeys(label.values, 0)
        numb_examples = len(examples)
        for example in examples:
            label_counts[example[-1]] += 1
        gi_s = 1
        for label_count in label_counts:
            gi_s -= ((label_counts[label_count] / numb_examples) ** 2)
        greatest_gain = 0
        greatest_gain_name = gini_index_attributes[0].attribute_name
        for gini_index_i, attribute in enumerate(gini_index_attributes):
            if not attribute.is_label and attribute.in_attributes:
                expected_gain = 0
                if attribute.is_numeric:
                    values_numeric = {'g': 0, 'le': 0}
                    label_values_numeric = dict.fromkeys(label.values, 0)
                    for example in examples:
                        if example[gini_index_i] <= attribute.median:
                            values_numeric['le'] += 1
                            label_values_numeric[example[-1]] += 1
                    gi_val = 1
                    for label_value_numeric in label_values_numeric:
                        if values_numeric['le'] != 0:
                            gi_val -= ((label_values_numeric[label_value_numeric] / values_numeric['le']) ** 2)
                    expected_gain += ((values_numeric['le'] / numb_examples) * gi_val)
                    label_values_numeric = dict.fromkeys(label.values, 0)
                    for example in examples:
                        if example[gini_index_i] > attribute.median:
                            values_numeric['g'] += 1
                            label_values_numeric[example[-1]] += 1
                    gi_val = 1
                    for label_value_numeric in label_values_numeric:
                        if values_numeric['g'] != 0:
                            gi_val -= ((label_values_numeric[label_value_numeric] / values_numeric['g']) ** 2)
                    expected_gain += ((values_numeric['g'] / numb_examples) * gi_val)
                else:
                    attribute_vals = attribute.values
                    for value in attribute_vals:
                        label_values = dict.fromkeys(label.values, 0)
                        value_count = 0
                        for example in examples:
                            if example[gini_index_i] == value:
                                label_values[example[-1]] += 1
                                value_count += 1
                        gi_val = 1
                        for label_value in label_values:
                            if value_count != 0:
                                gi_val -= ((label_values[label_value] / value_count) ** 2)
                        expected_gain += ((value_count / numb_examples) * gi_val)
                gain = gi_s - expected_gain
                if gain >= greatest_gain:
                    greatest_gain = gain
                    greatest_gain_name = attribute.attribute_name
        return greatest_gain_name


import random
import sqlite3

# ============= create account ===========

is_exit = False

def create_pin():
    return str(int(random.random() * 1e4)).zfill(4)

def create_checksum(string):
    accum = 0
    for i in reversed(range(len(string))):
        val = int(string[i]) * (1 if i % 2 else 2)
        accum += val if val <= 9 else val - 9
    return (10 - accum % 10) if accum % 10 > 0 else 0

def create_account():
    bank_id_st = '400000'
    act_st = str(int(random.random() * 1e6)).zfill(9)
    checksum_st = str(create_checksum(bank_id_st + act_st))
    return bank_id_st + act_st + checksum_st

def enter_acct():
    acct = input('Enter your card number:\n')
    if len(acct) != 16 or not acct.isnumeric():
        print('Invalid card number')
        return False
    lpin = input('Enter your PIN:\n')
    if len(lpin) != 4 or not lpin.isnumeric():
        print('Invalid PIN')
        return False
    query = "SELECT pin FROM card WHERE  number = '{}'".format(acct)
    cursor.execute(query)
    results = cursor.fetchone()
    if results is None:
        print('Wrong card number or PIN')
        return False
    if lpin != results[0]:
        print('Wrong card number or PIN')
        return False
    print('You have successfully logged in!')
    return acct

def get_balance(card_number):
    query = "SELECT balance FROM card WHERE  number = '{}'".format(card_number)
    cursor.execute(query)
    return int(cursor.fetchone()[0])

def add_income(card_number, addition):
    query = "UPDATE card SET balance = balance + {} WHERE number = {}".format(addition, card_number)
    cursor.execute(query)
    connection.commit()

def close_account(card_number):
    query = "DELETE FROM card WHERE number = {}".format(card_number)
    cursor.execute(query)
    connection.commit()

def has_enough_money(card_number, transfer_amount):
    if get_balance(card_number) < transfer_amount:
        return False
    return True

def is_card_exists(card_number):
    query = "SELECT * FROM card WHERE  number = '{}'".format(card_number)
    cursor.execute(query)
    return not cursor.fetchone() is None

def execute_transaction(from_card, to_card, amount):
    add_income(from_card, -1 * amount)
    add_income(to_card, amount)

def luhn_checksum(card_number):
    def digits_of(n):
        return [int(d) for d in str(n)]

    digits = digits_of(card_number)
    odd_digits = digits[-1::-2]
    even_digits = digits[-2::-2]
    checksum = 0
    checksum += sum(odd_digits)
    for d in even_digits:
        checksum += sum(digits_of(d * 2))
    return checksum % 10

def is_luhn_valid(card_number):
    return luhn_checksum(card_number) == 0

# ============= MAIN ============
connection = sqlite3.connect('card.s3db')
cursor = connection.cursor()
command1 = '''CREATE TABLE IF NOT EXISTS card
(id INTEGER, number TEXT, pin TEXT, balance INTEGER DEFAULT 0)'''
cursor.execute(command1)

while True:
    # ============= User input ============
    choice = int(input('1. Create an account\n'
                       '2. Log into account\n'
                       '0. Exit'))
    if choice == 0:
        print('Bye!')
        connection.commit()
        break

    if choice == 1:
        try:
            card_num = create_account()
            print('Your card has been created')
            print('Your card number:\n{}'.format(card_num))
            pin = create_pin()
            print('Your card PIN:\n{}'.format(pin))
            cmd = "INSERT INTO card (number, pin) VALUES('{}', '{}')".format(card_num, pin)
            cursor.execute(cmd)
            connection.commit()
        except sqlite3.OperationalError:
            print('invalid attempt to append to database ----------')
            print('attempting to add {} with pin {} to\n'.format(card_num, pin))
            cursor.execute('SELECT * FROM card')
            results = cursor.fetchall()
            print(len(results))
            print(results)

    elif choice == 2:
        c_num = enter_acct()
        while True:
            if c_num:
                print('1. Balance\n'
                      '2. Add income\n'
                      '3. Do transfer\n'
                      '4. Close account\n'
                      '5. Log out\n'
                      '0. Exit')
            else:
                break
            choice2 = int(input())

            if choice2 == 1:
                print("Balance:", get_balance(c_num))
            elif choice2 == 2:
                income = int(input("Enter income:\n"))
                add_income(c_num, income)
                print("Income was added!\n")
            elif choice2 == 3:
                print("Transfer")
                t_card_number = input("Enter card number:\n")
                if t_card_number != c_num:
                    if is_luhn_valid(t_card_number):
                        if is_card_exists(t_card_number):
                            t_amount = int(input("Enter how much money you want to transfer:"))
                            if has_enough_money(c_num, t_amount):
                                execute_transaction(c_num, t_card_number, t_amount)
                            else:
                                print("Not enough money!")
                        else:
                            print("Such a card does not exist.")
                    else:
                        print("Probably you made mistake in the card number. Please try again!")
                else:
                    print("You can't transfer money to the same account!")
            elif choice2 == 4:
                close_account(c_num)
                print("\nThe account has been closed!\n")
                break
            elif choice2 == 5:
                print('You have successfully logged out!')
                break
            elif choice2 == 0:
                is_exit = True
                break
    if is_exit:
        break


import pandas
import math

from models.demographics import Demographics

class DemographicsController:

    def __init__(self, file_name, database):
        self.df = pandas.read_csv(file_name)
        self.rows = self.df.shape[0]
        self.database = database

    def init_table_values(self):
        Demographics.drop_table(self.database)
        Demographics.create_table(self.database)

        for i in range(self.rows):
            person_id = int(self.df['respid'][i])
            sex = int(self.df['sex'][i])
            age = int(self.df['age'][i])
            if age > 97:
                age = None
            maritalStatus = int(self.df['marital'][i])
            if maritalStatus > 6:
                maritalStatus = None
            education = int(self.df['educ2'][i])
            if education > 8:
                education = None
            employment = int(self.df['emplnw'][i])
            if employment > 8:
                employment = None
            race = self.get_person_race(i)
            income = int(self.df['inc'][i])
            if income > 9:
                income = None
            party = int(self.df['party'][i])
            if party > 5:
                party = None
            partyLean = 0
            if not math.isnan(self.df['partyln'][i]):
                partyLean = int(self.df['partyln'][i])

            data = {'sex': sex, 'age': age, 'maritalStatus': maritalStatus,
                    'education': education, 'employment': employment,
                    'race': race, 'income': income, 'party': party, 'partyLean': partyLean}
            demographic_p = Demographics(self.database, person_id, data)
            demographic_p.save()

    """
    Gets a bit-encoded integer represents of all the races
    this person is
    """
    def get_person_race(self, i):
        race1 = int(self.df['racem1'][i])
        race2 = self.df['racem2'][i]
        race3 = self.df['racem3'][i]
        race4 = self.df['racem4'][i]
        if race1 > 7:  # refused to answer
            return None
        overall_race = (1 << race1)
        if not math.isnan(race2):
            overall_race |= (1 << int(race2))
        if not math.isnan(race3):
            overall_race |= (1 << int(race3))
        if not math.isnan(race4):
            overall_race |= (1 << int(race4))
        return overall_race


from django.db import models

# Create your models here.

class Subscription(models.Model):
    customer = models.ForeignKey('customer.Customer')
    package = models.ForeignKey('package.Package')
    created_at = models.DateTimeField(auto_now_add=True, null=False)
    updated_at = models.DateTimeField(auto_now=True, null=False)
    startdate = models.DateField(max_length=255, null=False)
    enddate = models.DateField(max_length=255, null=False)
    sessionsleft = models.IntegerField()
    flexiflag = models.BooleanField()
    expiryflag = models.BooleanField()


total_price = 0

family_info = [('Brad', 14), ('David', 44), ('Monica', 6)]

for name, age in family_info:

    if age < 3:
        continue
    elif 3 <= age <= 12:
        total_price += 10
    else:
        total_price += 15

print("Total price:", total_price)

teenagers = ['Adam', 'Roy', 'Billy']
teenagers_info = []

for teenager in teenagers:

    age = input(f"Hi {teenager}, What's your age? ")
    age_int = int(age)
    info = (teenager, age_int)
    teenagers_info.append(info)

eligible = []
for name, age in teenagers_info:

    if 16 < age < 21:
        continue
    eligible.append(name)

print("Eligible:", eligible)


import math
import torch
import torch.nn as nn
import torch.nn.functional as F

class GCNLayer(nn.Module):
    """
        GCN layer, similar to https://arxiv.org/abs/1609.02907
        Implementation inspired by https://github.com/tkipf/pygcn
    """

    def __init__(self, in_features, out_features, bias=True, device='cpu'):
        """
        :param in_features:     size of the input per node
        :param out_features:    size of the output per node
        :param bias:            whether to add a learnable bias before the activation
        :param device:          device used for computation
        """
        super(GCNLayer, self).__init__()
        self.in_features = in_features
        self.out_features = out_features
        self.device = device
        self.W = nn.Parameter(torch.zeros(size=(in_features, out_features), device=device))
        if bias:
            self.b = nn.Parameter(torch.zeros(out_features, device=device))
        else:
            self.register_parameter('b', None)
        self.reset_parameters()

    def reset_parameters(self):
        stdv = 1. / math.sqrt(self.W.size(1))
        self.W.data.uniform_(-stdv, stdv)
        if self.b is not None:
            self.b.data.uniform_(-stdv, stdv)

    def forward(self, X, adj):
        (B, N, _) = adj.shape

        # linear transformation
        XW = torch.matmul(X, self.W)

        # normalised mean aggregation
        adj = adj + torch.eye(N, device=self.device).unsqueeze(0)
        rD = torch.mul(torch.pow(torch.sum(adj, -1, keepdim=True), -0.5),
                       torch.eye(N, device=self.device).unsqueeze(0))  # D^{-1/2]
        adj = torch.matmul(torch.matmul(rD, adj), rD)  # D^{-1/2] A' D^{-1/2]
        y = torch.bmm(adj, XW)

        if self.b is not None:
            y = y + self.b
        return F.leaky_relu(y)

    def __repr__(self):
        return self.__class__.__name__ + ' (' \
               + str(self.in_features) + ' -> ' \
               + str(self.out_features) + ')'


from rest_framework.permissions import BasePermission

from .models import Ticket

class TicketOwnerOrAssignee(BasePermission):
    def has_permission(self, request, view):
        user_id = request.user.id
        ticket_id = view.kwargs.get("pk")
        ticket = Ticket.objects.get(id=ticket_id)
        return ticket.member.user.id == user_id or ticket.assignee.user.id == user_id


# The main program to create and send text messages to clients.
# Created By: AJ Singh
# Date: Jan 12, 2021

from extract_client_data import extract_client_data
from create_text_messages import create_text_messages
from calendar import month_name
from os.path import dirname

def main():

    excel_path = input("\nWhat is the path to the Excel file: \n")
    month = input("\nEnter full name of month: ").capitalize()
    while month not in list(month_name):
        month = input("\nInvalid input. Enter full name of month: ").capitalize()

    directory = dirname(excel_path)
    month_file = directory + f"\\{month}.txt"

    extract_client_data(excel_path, month)
    create_text_messages(month_file)

if __name__ == "__main__":
    main()


from itertools import combinations

import numpy as np
from pyparsing import Combine, Literal, Optional, Regex, Word, alphas, nums

from pgmpy.factors.discrete import DiscreteFactor, TabularCPD
from pgmpy.models import BayesianNetwork, MarkovNetwork
from pgmpy.utils import compat_fns

class UAIReader(object):
    """
    Initialize an instance of UAI reader class

    Parameters
    ----------
    path : file or str
        Path of the file containing UAI information.

    string : str
        String containing UAI information.

    Examples
    --------
    >>> from pgmpy.readwrite import UAIReader
    >>> reader = UAIReader('TestUai.uai')
    >>> model = reader.get_model()

    Reference
    ---------
    [1] https://uaicompetition.github.io/uci-2022/file-formats/model-format/
    [2] https://forgemia.inra.fr/thomas.schiex/toulbar2/-/blob/master/doc/UAI08Format.txt
    """

    def __init__(self, path=None, string=None):
        if path:
            with open(path, "r") as f:
                self.network = f.read()
        elif string:
            self.network = string
        else:
            raise ValueError("Must specify either path or string.")

        if "#" in self.network:
            self.network = (
                Regex("#.*").suppress().transformString(self.network)
            )  # removing comments from the file

        self.grammar = self.get_grammar()
        self.network_type = self.get_network_type()
        self.variables = self.get_variables()
        self.domain = self.get_domain()
        self.edges = self.get_edges()
        self.tables = self.get_tables()

    def get_grammar(self):
        """
        Returns the grammar of the UAI file.
        """
        network_name = Word(alphas).setResultsName("network_name")
        no_variables = Word(nums).setResultsName("no_variables")
        grammar = network_name + no_variables
        self.no_variables = int(grammar.parseString(self.network)["no_variables"])
        domain_variables = (Word(nums) * self.no_variables).setResultsName(
            "domain_variables"
        )
        grammar += domain_variables
        no_functions = Word(nums).setResultsName("no_functions")
        grammar += no_functions
        self.no_functions = int(grammar.parseString(self.network)["no_functions"])
        integer = Word(nums).setParseAction(lambda t: int(t[0]))
        for function in range(0, self.no_functions):
            scope_grammar = Word(nums).setResultsName("fun_scope_" + str(function))
            grammar += scope_grammar
            function_scope = grammar.parseString(self.network)[
                "fun_scope_" + str(function)
            ]
            function_grammar = ((integer) * int(function_scope)).setResultsName(
                "fun_" + str(function)
            )
            grammar += function_grammar

        floatnumber = Combine(
            Word(nums) + Optional(Literal(".") + Optional(Word(nums)))
        )
        for function in range(0, self.no_functions):
            no_values_grammar = Word(nums).setResultsName(
                "fun_no_values_" + str(function)
            )
            grammar += no_values_grammar
            no_values = grammar.parseString(self.network)[
                "fun_no_values_" + str(function)
            ]
            values_grammar = ((floatnumber) * int(no_values)).setResultsName(
                "fun_values_" + str(function)
            )
            grammar += values_grammar
        return grammar

    def get_network_type(self):
        """
        Returns the type of network defined by the file.

        Returns
        -------
        string : str
            String containing network type.

        Examples
        --------
        >>> from pgmpy.readwrite import UAIReader
        >>> reader = UAIReader('TestUAI.uai')
        >>> reader.get_network_type()
        'MARKOV'
        """
        network_type = self.grammar.parseString(self.network)
        return network_type["network_name"]

    def get_variables(self):
        """
        Returns a list of variables.
        Each variable is represented by an index of list.
        For example if the no of variables are 4 then the list will be
        [var_0, var_1, var_2, var_3]

        Returns
        -------
        list: list of variables

        Examples
        --------
        >>> from pgmpy.readwrite import UAIReader
        >>> reader = UAIReader('TestUAI.uai')
        >>> reader.get_variables()
        ['var_0', 'var_1', 'var_2']
        """
        variables = []
        for var in range(0, self.no_variables):
            var_name = "var_" + str(var)
            variables.append(var_name)
        return variables

    def get_domain(self):
        """
        Returns the dictionary of variables with keys as variable name
        and values as domain of the variables.

        Returns
        -------
        dict: dictionary containing variables and their domains

        Examples
        --------
        >>> from pgmpy.readwrite import UAIReader
        >>> reader = UAIReader('TestUAI.uai')
        >>> reader.get_domain()
        {'var_0': '2', 'var_1': '2', 'var_2': '3'}
        """
        domain = {}
        var_domain = self.grammar.parseString(self.network)["domain_variables"]
        for var in range(0, len(var_domain)):
            domain["var_" + str(var)] = var_domain[var]
        return domain

    def get_edges(self):
        """
        Returns the edges of the network.

        Returns
        -------
        set: set containing the edges of the network

        Examples
        --------
        >>> from pgmpy.readwrite import UAIReader
        >>> reader = UAIReader('TestUAI.uai')
        >>> reader.get_edges()
        {('var_0', 'var_1'), ('var_0', 'var_2'), ('var_1', 'var_2')}
        """
        edges = []
        for function in range(0, self.no_functions):
            function_variables = self.grammar.parseString(self.network)[
                "fun_" + str(function)
            ]
            if isinstance(function_variables, int):
                function_variables = [function_variables]
            if self.network_type == "BAYES":
                child_var = "var_" + str(function_variables[-1])
                function_variables = function_variables[:-1]
                for var in function_variables:
                    edges.append(("var_" + str(var), child_var))
            elif self.network_type == "MARKOV":
                function_variables = ["var_" + str(var) for var in function_variables]
                edges.extend(list(combinations(function_variables, 2)))
        return set(edges)

    def get_tables(self):
        """
        Returns list of tuple of child variable and CPD in case of Bayesian
        and list of tuple of scope of variables and values in case of Markov.

        Returns
        -------
        list : list of tuples of child variable and values in Bayesian
            list of tuples of scope of variables and values in case of Markov.

        Examples
        --------
        >>> from pgmpy.readwrite import UAIReader
        >>> reader = UAIReader('TestUAI.uai')
        >>> reader.get_tables()
        [(['var_0', 'var_1'], ['4.000', '2.400', '1.000', '0.000']),
         (['var_0', 'var_1', 'var_2'],
          ['2.2500', '3.2500', '3.7500', '0.0000', '0.0000', '10.0000',
           '1.8750', '4.0000', '3.3330', '2.0000', '2.0000', '3.4000'])]
        """
        tables = []
        for function in range(0, self.no_functions):
            function_variables = self.grammar.parseString(self.network)[
                "fun_" + str(function)
            ]
            if isinstance(function_variables, int):
                function_variables = [function_variables]
            if self.network_type == "BAYES":
                child_var = "var_" + str(function_variables[-1])
                values = self.grammar.parseString(self.network)[
                    "fun_values_" + str(function)
                ]
                tables.append((child_var, list(values)))
            elif self.network_type == "MARKOV":
                function_variables = ["var_" + str(var) for var in function_variables]
                values = self.grammar.parseString(self.network)[
                    "fun_values_" + str(function)
                ]
                tables.append((function_variables, list(values)))
        return tables

    def get_model(self):
        """
        Returns an instance of Bayesian Model or Markov Model.
        Variables are in the pattern var_0, var_1, var_2 where var_0 is
        0th index variable, var_1 is 1st index variable.

        Return
        ------
        model: an instance of Bayesian or Markov Model.

        Examples
        --------
        >>> from pgmpy.readwrite import UAIReader
        >>> reader = UAIReader('TestUAI.uai')
        >>> reader.get_model()
        """
        if self.network_type == "BAYES":
            model = BayesianNetwork()
            model.add_nodes_from(self.variables)
            model.add_edges_from(self.edges)

            tabular_cpds = []
            for child_var, values in self.tables:
                states = int(self.domain[child_var])
                values = np.fromiter(values, dtype=float)
                values = values.reshape(states, values.size // states)
                parents = list(model.predecessors(child_var))
                if len(parents) == 0:
                    tabular_cpds.append(TabularCPD(child_var, states, values))
                else:
                    tabular_cpds.append(
                        TabularCPD(
                            child_var,
                            states,
                            values,
                            evidence=parents,
                            evidence_card=[int(self.domain[var]) for var in parents],
                        )
                    )

            model.add_cpds(*tabular_cpds)
            return model

        elif self.network_type == "MARKOV":
            model = MarkovNetwork(self.edges)

            factors = []
            for table in self.tables:
                variables = table[0]
                cardinality = [int(self.domain[var]) for var in variables]
                value = list(map(float, table[1]))
                factor = DiscreteFactor(
                    variables=variables, cardinality=cardinality, values=value
                )
                factors.append(factor)

            model.add_factors(*factors)
            return model

class UAIWriter(object):
    """
    Initialize an instance of UAI writer class

    Parameters
    ----------
    model: A Bayesian or Markov model
        The model to write

    round_values: int (default: None)
        The number to decimals to which to round the probability values. If None, keeps all decimals points.

    Examples
    --------
    >>> from pgmpy.readwrite import UAIWriter
    >>> from pgmpy.utils import get_example_model
    >>> model = get_example_model('asia')
    >>> writer = UAIWriter(asia)
    >>> writer.write_uai('asia.uai')
    """

    def __init__(self, model, round_values=None):
        if isinstance(model, BayesianNetwork):
            self.network = "BAYES\n"
        elif isinstance(model, MarkovNetwork):
            self.network = "MARKOV\n"
        else:
            raise TypeError("Model must be an instance of Bayesian or Markov model.")

        self.model = model
        self.round_values = round_values
        self.no_nodes = self.get_nodes()
        self.domain = self.get_domain()
        self.functions = self.get_functions()
        self.tables = self.get_tables()

    def __str__(self):
        """
        Returns the UAI file as a string.
        """
        self.network += self.no_nodes + "\n"
        domain = sorted(self.domain.items(), key=lambda x: (x[1], x[0]))
        self.network += " ".join([var[1] for var in domain]) + "\n"
        self.network += str(len(self.functions)) + "\n"
        for fun in self.functions:
            self.network += str(len(fun)) + " "
            self.network += " ".join(fun) + "\n"
        self.network += "\n"
        for table in self.tables:
            self.network += str(len(table)) + "\n"
            self.network += " ".join(table) + "\n"
        return self.network[:-1]

    def get_nodes(self):
        """
        Adds variables to the network.

        Examples
        --------
        >>> from pgmpy.readwrite import UAIWriter
        >>> writer = UAIWriter(model)
        >>> writer.get_nodes()
        """
        no_nodes = len(self.model.nodes())
        return str(no_nodes)

    def get_domain(self):
        """
        Adds domain of each variable to the network.

        Examples
        --------
        >>> from pgmpy.readwrite import UAIWriter
        >>> writer = UAIWriter(model)
        >>> writer.get_domain()
        """
        if isinstance(self.model, BayesianNetwork):
            cpds = self.model.get_cpds()
            cpds.sort(key=lambda x: x.variable)
            domain = {}
            for cpd in cpds:
                domain[cpd.variable] = str(cpd.variable_card)
            return domain
        elif isinstance(self.model, MarkovNetwork):
            factors = self.model.get_factors()
            domain = {}
            for factor in factors:
                variables = factor.variables
                for var in variables:
                    if var not in domain:
                        domain[var] = str(factor.get_cardinality([var])[var])
            return domain
        else:
            raise TypeError("Model must be an instance of Markov or Bayesian model.")

    def get_functions(self):
        """
        Adds functions to the network.

        Examples
        -------_
        >>> from pgmpy.readwrite import UAIWriter
        >>> writer = UAIWriter(model)
        >>> writer.get_functions()
        """
        if isinstance(self.model, BayesianNetwork):
            cpds = self.model.get_cpds()
            cpds.sort(key=lambda x: x.variable)
            variables = sorted(self.domain.items(), key=lambda x: (x[1], x[0]))
            functions = []
            for cpd in cpds:
                child_var = cpd.variable
                evidence = cpd.variables[:0:-1]
                function = [
                    str(variables.index((var, self.domain[var]))) for var in evidence
                ]
                function.append(
                    str(variables.index((child_var, self.domain[child_var])))
                )
                functions.append(function)
            return functions
        elif isinstance(self.model, MarkovNetwork):
            factors = self.model.get_factors()
            functions = []
            variables = sorted(self.domain.items(), key=lambda x: (x[1], x[0]))
            for factor in factors:
                scope = factor.scope()
                function = [
                    str(variables.index((var, self.domain[var]))) for var in scope
                ]
                functions.append(function)
            return functions
        else:
            raise TypeError("Model must be an instance of Markov or Bayesian model.")

    def get_tables(self):
        """
        Adds tables to the network.

        Examples
        --------
        >>> from pgmpy.readwrite import UAIWriter
        >>> writer = UAIWriter(model)
        >>> writer.get_tables()
        """
        if isinstance(self.model, BayesianNetwork):
            cpds = self.model.get_cpds()
            cpds.sort(key=lambda x: x.variable)
            tables = []
            for cpd in cpds:
                values = list(
                    map(
                        str,
                        compat_fns.to_numpy(
                            cpd.values.ravel(), decimals=self.round_values
                        ),
                    )
                )
                tables.append(values)
            return tables
        elif isinstance(self.model, MarkovNetwork):
            factors = self.model.get_factors()
            tables = []
            for factor in factors:
                values = list(
                    map(
                        str,
                        compat_fns.to_numpy(
                            factor.values.ravel(), decimals=self.round_values
                        ),
                    )
                )
                tables.append(values)
            return tables
        else:
            raise TypeError("Model must be an instance of Markov or Bayesian model.")

    def write_uai(self, filename):
        """
        Write the xml data into the file.

        Parameters
        ----------
        filename: Name of the file.

        Examples
        --------
        >>> from pgmpy.readwrite import UAIWriter
        >>> from pgmpy.utils import get_example_model
        >>> model = get_example_model('asia')
        >>> writer = UAIWriter(asia)
        >>> writer.write_uai('asia.uai')
        """
        writer = self.__str__()
        with open(filename, "w") as fout:
            fout.write(writer)