from llvmAnalyser.llvmChecker import *
from llvmAnalyser.llvmStatement import LlvmStatement
from llvmAnalyser.function import Parameter as Argument
from llvmAnalyser.conversion.conversion import analyze_conversion
from llvmAnalyser.values import get_value
from llvmAnalyser.types import get_type

# The ‘invoke’ instruction causes control to transfer to a specified function,
# with the possibility of control flow transfer to either the ‘normal’ label or the ‘exception’ label.
# If the callee function returns with the “ret” instruction, control flow will return to the “normal” label.
# If the callee (or any indirect callees) returns via the “resume” instruction or other exception handling mechanism,
# control is interrupted and continued at the dynamically nearest “exception” label.
#
# The ‘exception’ label is a landing pad for the exception.
# As such, ‘exception’ label is required to have the “landingpad” instruction,
# which contains the information about the behavior of the program after unwinding happens,
# as its first non-PHI instruction. The restrictions on the “landingpad” instruction’s tightly couples it to the
# “invoke” instruction, so that the important information contained within the “landingpad” instruction can’t be
# lost through normal code motion.
#
# <result> = invoke [cconv] [ret attrs] [addrspace(<num>)] <ty>|<fnty> <fnptrval>(<function args>) [fn attrs]
#              [operand bundles] to label <normal label> unwind label <exception label>

def analyze_invoke(tokens):
    invoke = Invoke()

    # pop potential assignment
    while tokens[0] != "invoke":
        tokens.pop(0)

    tokens.pop(0)

    # pop calling convention
    if is_calling_convention(tokens[0]):
        attr = tokens.pop(0)
        if attr == "cc":
            attr += " {}".format(tokens.pop(0))
        invoke.set_calling_conv(attr)
    else:
        invoke.set_calling_conv("ccc")

    # check if there are parameter attributes
    while is_parameter_attribute(tokens[0]):
        open_brackets = tokens[0].count("(") - tokens[0].count(")")
        attr = tokens.pop(0)
        while open_brackets != 0:
            open_brackets += tokens[0].count("(") - tokens[0].count(")")
            attr += " {}".format(tokens.pop(0))
        invoke.add_ret_attr(attr)

    # pop optional address space field
    if is_address_space(tokens[0]):
        tokens.pop(0)

    # pop return type
    return_type, tokens = get_type(tokens)
    invoke.set_return_type(return_type)

    # get the function name
    if "bitcast" in tokens[0]:
        conversion = analyze_conversion(tokens)
        invoke.set_func(conversion.get_value())
        if tokens[0][0] == "(":
            tokens[0] = tokens[0][1:]
    else:
        temp = tokens[0].split("(", 1)
        tokens[0] = temp[1]

        invoke.set_func(temp[0])

    while tokens:
        if tokens[0] == ")":
            tokens.pop(0)
            break

        count = 0
        for token in tokens:
            count += token.count("(") - token.count(")")
        if count == 0:
            break

        argument = Argument()

        # read argument type
        parameter_type, tokens = get_type(tokens)
        argument.set_parameter_type(parameter_type)

        # read potential parameter attributes
        while is_parameter_attribute(tokens[0]):
            open_brackets = tokens[0].count("(") - tokens[0].count(")")
            attribute = tokens.pop(0)
            while open_brackets != 0 or attribute == "align":
                open_brackets += tokens[0].count("(") - tokens[0].count(")")
                attribute += " {}".format(tokens.pop(0))
            argument.add_parameter_attribute(attribute)

        # read register
        value, tokens = get_value(tokens)
        argument.set_register(value)

        invoke.add_argument(argument)

    # read function attributes
    if tokens and is_group_attribute(tokens[0]):
        invoke.add_fn_attr(tokens[0])
        tokens.pop(0)
    while tokens and is_function_attribute(tokens[0]):
        if "allocsize" in tokens[0]:
            attribute = tokens.pop(0)
            open_brackets = attribute.count("(") - attribute.count(")")
            while open_brackets != 0:
                open_brackets += tokens[0].count("(") - tokens[0].count(")")
                attribute += " {}".format(tokens.pop(0))
            invoke.add_fn_attr(attribute)
        else:
            invoke.add_fn_attr(tokens.pop(0))

    # analyze operand bundle sets
    if tokens and "[" in tokens[0]:
        operand_bundle_set = OperandBundleSet()
        tokens.pop(0)

        # analyze operand bundles
        while tokens[0] != "]":
            operand_bundle = OperandBundle()

            # get the operand bundle tag
            quote_count = tokens[0].count("\"")
            tag = tokens.pop(0)
            while quote_count < 2:
                tag += " {}".format(tokens.pop(0))
                quote_count = tag.count("\"")

            temp = tag.split('"', 2)
            operand_bundle.set_tag("\"{}\"".format(temp[1]))
            tokens.insert(0, temp[-1])

            desired_remaining_token_length = get_nr_of_tokens_past_last_bracket(tokens)

            if tokens[0][0] == ")":
                operand_bundle_set.add_operand_bundle(operand_bundle)
                tokens.pop(0)
                continue

            # analyze operands
            while len(tokens) > desired_remaining_token_length:
                operand = Operand()

                operand_type, tokens = get_type(tokens)
                operand.set_type(operand_type)

                operand_value, tokens = get_value(tokens)
                operand.set_value(operand_value)

                operand_bundle.add_operand(operand)

            operand_bundle_set.add_operand_bundle(operand_bundle)

        invoke.set_operand_bundle_set(operand_bundle_set)

        # pop the ] token
        tokens.pop(0)

    # skip to the normal label
    tokens.pop(0)

    # pop label tag
    tokens.pop(0)

    invoke.set_normal(tokens[0].split("(")[0])
    tokens.pop(0)

    # pop "unwind label"
    tokens.pop(0)
    tokens.pop(0)
    invoke.set_exception(tokens[0].split("(")[0])

    return invoke

def get_nr_of_tokens_past_last_bracket(tokens):
    tokens[0] = tokens[0][1:]

    open_brackets = 1

    # loop over the tokens until this first bracket is closed again, when this happens, return the index
    for i in range(len(tokens)):
        for j in range(len(tokens[i])):
            char = tokens[i][j]
            if char == "(":
                open_brackets += 1
            elif char == ")":
                open_brackets -= 1
            if open_brackets == 0:
                return len(tokens) - i

class Invoke(LlvmStatement):
    def __init__(self):
        super().__init__()
        self.func = None
        self.normal = None
        self.exception = None
        self.arguments = list()
        self.fn_attrs = list()
        self.operand_bundle_set = None
        self.cconv = None
        self.ret_attrs = list()
        self.return_type = None

    def set_return_type(self, return_type):
        self.return_type = return_type

    def returns_pointer(self):
        return self.return_type[-1] == "*"

    def set_func(self, func):
        self.func = func

    def get_function_name(self):
        return self.func

    def set_normal(self, normal):
        self.normal = normal

    def get_normal(self):
        return self.normal

    def set_exception(self, exception):
        self.exception = exception

    def get_exception(self):
        return self.exception

    def add_argument(self, argument):
        self.arguments.append(argument)

    def get_arguments(self):
        return self.arguments

    def get_argument_registers(self):
        registers = list()
        for argument in self.arguments:
            registers.append(argument.get_register())
        return registers

    def add_fn_attr(self, fn_attr):
        self.fn_attrs.append(fn_attr)

    def get_fn_attrs(self):
        return self.fn_attrs

    def set_operand_bundle_set(self, op_set):
        self.operand_bundle_set = op_set

    def get_operand_bundle_set(self):
        return self.operand_bundle_set

    def set_calling_conv(self, cconv):
        self.cconv = cconv

    def get_calling_conv(self):
        return self.cconv

    def add_ret_attr(self, attr):
        self.ret_attrs.append(attr)

    def get_ret_attrs(self):
        return self.ret_attrs

    def get_used_variables(self):
        variable_values = list()
        for argument in self.arguments:
            variable_values.append(argument.get_register())
        return variable_values

    def __str__(self):
        output = "invoke {}\n".format(self.func)
        if len(self.arguments) != 0:
            output += "\t{} parameter(s):\n".format(len(self.arguments))
            for parameter in self.arguments:
                output += "\t\t{}\n".format(str(parameter))
        else:
            output += "\t0 parameters\n"

        if len(self.fn_attrs) != 0:
            output += "\tfunction attributes = {}\n".format(self.fn_attrs)
        return output

class OperandBundleSet:
    def __init__(self):
        self.operand_bundles = list()

    def add_operand_bundle(self, bundle):
        self.operand_bundles.append(bundle)

    def get_operand_bundles(self):
        return self.operand_bundles

class OperandBundle:
    def __init__(self):
        self.tag = None
        self.operands = list()

    def set_tag(self, tag):
        self.tag = tag

    def get_tag(self):
        return self.tag

    def add_operand(self, operand):
        self.operands.append(operand)

    def get_operands(self):
        return self.operands

class Operand:
    def __init__(self):
        self.operand_type = None
        self.operand_value = None

    def set_value(self, operand_value):
        self.operand_value = operand_value

    def get_value(self):
        return self.operand_value

    def set_type(self, operand_type):
        self.operand_type = operand_type

    def get_type(self):
        return self.operand_type


#!/usr/bin/env python3

import sys

fns = sys.argv[1:]

ERR_COP = 0 # copyright header
ERR_IMP = 1 # import statements
ERR_MOD = 2 # module docstring
ERR_LIN = 3 # line length
ERR_SAV = 4 # ᾰ
ERR_RNT = 5 # reserved notation
ERR_OPT = 6 # set_option

exceptions = []

with open("scripts/style-exceptions.txt", encoding="utf-8") as f:
    for line in f.readlines():
        fn, _, _, _, _, errno, *_ = line.split()
        if errno == "ERR_COP":
            exceptions += [(ERR_COP, fn)]
        if errno == "ERR_IMP":
            exceptions += [(ERR_IMP, fn)]
        if errno == "ERR_MOD":
            exceptions += [(ERR_MOD, fn)]
        if errno == "ERR_LIN":
            exceptions += [(ERR_LIN, fn)]
        if errno == "ERR_SAV":
            exceptions += [(ERR_SAV, fn)]
        if errno == "ERR_RNT":
            exceptions += [(ERR_RNT, fn)]
        if errno == "ERR_OPT":
            exceptions += [(ERR_OPT, fn)]

new_exceptions = False

def skip_comments(enumerate_lines):
    in_comment = False
    for line_nr, line in enumerate_lines:
        if "/-" in line:
            in_comment = True
        if "-/" in line:
            in_comment = False
            continue
        if line == "\n" or in_comment:
            continue
        yield line_nr, line

def skip_string(enumerate_lines):
    in_string = False
    in_comment = False
    for line_nr, line in enumerate_lines:
        # ignore comment markers inside string literals
        if not in_string:
            if "/-" in line:
                in_comment = True
            if "-/" in line:
                in_comment = False
        # ignore quotes inside comments
        if not in_comment:
            # crude heuristic: if the number of non-escaped quote signs is odd,
            # we're starting / ending a string literal
            if line.count("\"") - line.count("\\\"") % 2 == 1:
                in_string = not in_string
            # if there are quote signs in this line,
            # a string literal probably begins and / or ends here,
            # so we skip this line
            if line.count("\"") > 0:
                continue
            if in_string:
                continue
        yield line_nr, line

def small_alpha_vrachy_check(lines, fn):
    errors = []
    for line_nr, line in skip_string(skip_comments(enumerate(lines, 1))):
        if 'ᾰ' in line:
            errors += [(ERR_SAV, line_nr, fn)]
    return errors

def reserved_notation_check(lines, fn):
    if fn == 'src/tactic/reserved_notation.lean':
        return []
    errors = []
    for line_nr, line in skip_string(skip_comments(enumerate(lines, 1))):
        if line.startswith('reserve') or line.startswith('precedence'):
            errors += [(ERR_RNT, line_nr, fn)]
    return errors

def set_option_check(lines, fn):
    errors = []
    for line_nr, line in skip_string(skip_comments(enumerate(lines, 1))):
        if line.startswith('set_option'):
            next_two_chars = line.split(' ')[1][:2]
            # forbidden options: pp, profiler, trace
            if next_two_chars == 'pp' or next_two_chars == 'pr' or next_two_chars == 'tr':
                errors += [(ERR_OPT, line_nr, fn)]
    return errors

def long_lines_check(lines, fn):
    errors = []
    # TODO: some string literals (in e.g. tactic output messages) can be excepted from this rule
    for line_nr, line in enumerate(lines, 1):
        if "http" in line:
            continue
        if len(line) > 101:
            errors += [(ERR_LIN, line_nr, fn)]
    return errors

def import_only_check(lines, fn):
    import_only_file = True
    errors = []
    for line_nr, line in skip_comments(enumerate(lines, 1)):
        imports = line.split()
        if imports[0] == "--":
            continue
        if imports[0] != "import":
            import_only_file = False
            break
        if len(imports) > 2:
            if imports[2] == "--":
                continue
            else:
                errors += [(ERR_IMP, line_nr, fn)]
    return (import_only_file, errors)

def regular_check(lines, fn):
    errors = []
    copy_started = False
    copy_done = False
    copy_start_line_nr = 0
    copy_lines = ""
    for line_nr, line in enumerate(lines, 1):
        if not copy_started and line == "\n":
            errors += [(ERR_COP, copy_start_line_nr, fn)]
            continue
        if not copy_started and line == "/-\n":
            copy_started = True
            copy_start_line_nr = line_nr
            continue
        if not copy_started:
            errors += [(ERR_COP, line_nr, fn)]
        if copy_started and not copy_done:
            copy_lines += line
            if line == "-/\n":
                if ((not "Copyright" in copy_lines) or
                    (not "Apache" in copy_lines) or
                    (not "Author" in copy_lines)):
                    errors += [(ERR_COP, copy_start_line_nr, fn)]
                copy_done = True
            continue
        if copy_done and line == "\n":
            continue
        words = line.split()
        if words[0] != "import" and words[0] != "/-!":
            errors += [(ERR_MOD, line_nr, fn)]
            break
        if words[0] == "/-!":
            break
        # final case: words[0] == "import"
        if len(words) > 2:
            if words[2] != "--":
                errors += [(ERR_IMP, line_nr, fn)]
    return errors

def format_errors(errors):
    global new_exceptions
    for (errno, line_nr, fn) in errors:
        if (errno, fn) in exceptions:
            continue
        new_exceptions = True
        # filename first, then line so that we can call "sort" on the output
        if errno == ERR_COP:
            print("{} : line {} : ERR_COP : Malformed or missing copyright header".format(fn, line_nr))
        if errno == ERR_IMP:
            print("{} : line {} : ERR_IMP : More than one file imported per line".format(fn, line_nr))
        if errno == ERR_MOD:
            print("{} : line {} : ERR_MOD : Module docstring missing, or too late".format(fn, line_nr))
        if errno == ERR_LIN:
            print("{} : line {} : ERR_LIN : Line has more than 100 characters".format(fn, line_nr))
        if errno == ERR_SAV:
            print("{} : line {} : ERR_SAV : File contains the character ᾰ".format(fn, line_nr))
        if errno == ERR_RNT:
            print("{} : line {} : ERR_RNT : Reserved notation outside tactic.reserved_notation".format(fn, line_nr))
        if errno == ERR_OPT:
            print("{} : line {} : ERR_OPT : Forbidden set_option command".format(fn, line_nr))

def lint(fn):
    with open(fn, encoding="utf-8") as f:
        lines = f.readlines()
        errs = long_lines_check(lines, fn)
        format_errors(errs)
        (b, errs) = import_only_check(lines, fn)
        if b:
            format_errors(errs)
            return
        errs = regular_check(lines, fn)
        format_errors(errs)
        errs = small_alpha_vrachy_check(lines, fn)
        format_errors(errs)
        errs = reserved_notation_check(lines, fn)
        format_errors(errs)
        errs = set_option_check(lines, fn)
        format_errors(errs)

for fn in fns:
    lint(fn)

# if "exceptions" is empty,
# we're trying to generate style-exceptions.txt,
# so new exceptions are expected
if new_exceptions and len(exceptions) > 0:
    exit(1)


from hypothesis import given

from paradigm.base import (OverloadedSignature,
                           PlainSignature)
from tests.utils import AnySignature
from . import strategies

@given(strategies.signatures)
def test_type(signature: AnySignature) -> None:
    result = str(signature)

    assert isinstance(result, str)

@given(strategies.plain_signatures)
def test_plain(signature: PlainSignature) -> None:
    result = str(signature)

    assert all(str(parameter) in result for parameter in signature.parameters)

@given(strategies.overloaded_signatures)
def test_nesting(signature: OverloadedSignature) -> None:
    result = str(signature)

    assert all(str(signature) in result for signature in signature.signatures)


from datetime import date
from enum import Flag
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtGui as qtg
from PyQt5 import QtCore as qtc
import sys
class MainWindow(qtw.QWidget):
    events = {}
    def __init__(self):
        super().__init__()

        #UI CODE START
        self.setWindowTitle("Calendar App")
        self.resize(800,800)

        #Create Widgets
        self.calendar = qtw.QCalendarWidget()
        self.calendar.setGridVisible(True)
        self.calendar.setVerticalHeaderFormat(qtw.QCalendarWidget.NoVerticalHeader)
        self.calendar.setSelectionMode(qtw.QCalendarWidget.SingleSelection)
        self.event_list = qtw.QListWidget()
        self.event_title = qtw.QLineEdit()
        self.event_time = qtw.QTimeEdit(qtc.QTime(12,0))
        self.event_category = qtw.QComboBox()
        self.allday_check = qtw.QCheckBox("All day")
        self.event_deatil = qtw.QTextEdit()
        self.add_button = qtw.QPushButton("Add/Update")
        self.delete_button = qtw.QPushButton("Delete")

        #populate event category
        self.event_category.addItems(["Select Category...","New...","Work","Meeting","Home","Travel","Shopping"])
        self.event_category.model().item(0).setEnabled(False)

        #Calendar size policy
        self.calendar.setSizePolicy(qtw.QSizePolicy.Expanding,qtw.QSizePolicy.Expanding)

        #Event List size policy
        self.event_list.setSizePolicy(qtw.QSizePolicy.Expanding,qtw.QSizePolicy.Expanding)

        #GUI Layout
        main_layout = qtw.QHBoxLayout()
        self.setLayout(main_layout)
        main_layout.addWidget(self.calendar)

        right_layout = qtw.QVBoxLayout()
        main_layout.addLayout(right_layout)
        right_layout.addWidget(qtw.QLabel("Events on Date"))
        right_layout.addWidget(self.event_list)

        event_form = qtw.QGroupBox("Event")
        event_form_layout = qtw.QGridLayout()
        event_form.setLayout(event_form_layout)
        right_layout.addWidget(event_form)

        event_form_layout.addWidget(self.event_title,1,1,1,3)
        event_form_layout.addWidget(self.event_category,2,1)
        event_form_layout.addWidget(self.event_time,2,2)
        event_form_layout.addWidget(self.allday_check,2,3)
        event_form_layout.addWidget(self.event_deatil,3,1,1,3)
        event_form_layout.addWidget(self.add_button,4,1)
        event_form_layout.addWidget(self.delete_button,4,3)

        #Event Handling
        self.allday_check.toggled.connect(self.event_time.setDisabled)
        self.calendar.selectionChanged.connect(self.populate_list)
        self.event_list.itemSelectionChanged.connect(self.populate_form)
        self.event_list.itemSelectionChanged.connect(self.check_del_button)
        self.add_button.clicked.connect(self.save_event)
        self.delete_button.clicked.connect(self.delete_event)

        self.check_del_button()
        #UI CODE END
        self.show()

    def clear_form(self):
        print("clear_form func")
        self.event_time.setTime(qtc.QTime(8,0))
        self.event_title.clear()
        self.event_category.setCurrentIndex(0)
        self.event_deatil.setPlainText("")
        self.allday_check.setChecked(False)

    def populate_list(self):
        print("populate_list func")
        self.event_list.clear()
        self.clear_form()
        date = self.calendar.selectedDate()
        for event in self.events.get(date,[]):
            if event['time']:
                time = event['time'].toString('hh:mm')
            else:
                time = 'All Day'

            self.event_list.addItem(f"{time}:{event['title']}")

    def populate_form(self):
        print("populate_form func")
        self.clear_form()
        date = self.calendar.selectedDate()
        event_number = self.event_list.currentRow()
        print(event_number)
        if event_number == -1:
            return
        if not self.events.get(date,[]):
            return
        event_data = self.events.get(date)[event_number]
        self.event_category.setCurrentText(event_data['category'])
        self.event_deatil.setPlainText(event_data['detail'])
        if event_data['time']:
            self.event_time.setTime(event_data['time'])
        else:
            self.allday_check.setChecked(True)
        self.event_title.setText(event_data['title'])

    def save_event(self):
        print("save event func")
        event_data = {}
        date = self.calendar.selectedDate()
        event_data['category'] = self.event_category.currentText()
        event_data['detail'] = self.event_deatil.toPlainText()
        if self.allday_check.isChecked():
            event_data['time'] = None
        else:
            event_data['time'] = self.event_time.time()
        event_data['title'] = self.event_title.text()

        event_list = self.events.get(date,[])
        event_number = self.event_list.currentRow()
        if event_number == -1:
            event_list.append(event_data)
        else:
            event_list[event_number] = event_data

        event_list.sort(key=lambda e: e['time'] or qtc.QTime(0,0))
        self.events[date] = event_list
        self.populate_list()

    def delete_event(self):
        print("delete event func")
        date = self.calendar.selectedDate()
        row = self.event_list.currentRow()
        del(self.events[date][row])
        self.event_list.setCurrentRow(-1)
        self.clear_form()
        self.populate_list()

    def check_del_button(self):
        self.delete_button.setEnabled(
            self.event_list.currentRow() == -1
        )

if __name__ == '__main__':

    app = qtw.QApplication(sys.argv)

    mw = MainWindow()

    sys.exit(app.exec())


import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.entity as entity
import azlmbr.surface_data
import azlmbr.globals

# Open a level
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'OpenLevelNoPrompt', 'auto_test')

def print_result(message, result):
    if result:
        print(message + ": SUCCESS")
    else:
        print(message + ": FAILURE")

def is_container(pte, path):
    return pte.is_container(path)

def get_container_count(pte, path):
    outcome = pte.get_container_count(path)
    if(outcome.IsSuccess()):
        return outcome.GetValue()
    return False

def reset_container(pte, path):
    outcome = pte.reset_container(path)
    if(outcome.IsSuccess()):
        return outcome.GetValue()
    return False

def add_container_item(pte, path, key, item):
    outcome = pte.add_container_item(path, key, item)
    if(outcome.IsSuccess()):
        return outcome.GetValue()
    return False

def remove_container_item(pte, path, key):
    outcome = pte.remove_container_item(path, key)
    if(outcome.IsSuccess()):
        return outcome.GetValue()
    return False

def update_container_item(pte, path, key, value):
    outcome = pte.update_container_item(path, key, value)
    if(outcome.IsSuccess()):
        return outcome.GetValue()
    return False

def get_container_item(pte, path, key):
    outcome = pte.get_container_item(path, key)
    if(outcome.IsSuccess()):
        return outcome.GetValue()
    return False

# Create new Entity
entityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
print_result("New entity with no parent created", entityId)

tagOne = azlmbr.surface_data.SurfaceTag()
tagOne.SetTag('one')

tagTwo = azlmbr.surface_data.SurfaceTag()
tagTwo.SetTag('two')

tagThree = azlmbr.surface_data.SurfaceTag()
tagThree.SetTag('three')

tagFour = azlmbr.surface_data.SurfaceTag()
tagFour.SetTag('four')

# create a component with a TagSurface container
typeIdsList = [azlmbr.globals.property.GradientSurfaceDataComponentTypeId]

componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, typeIdsList)
if (componentOutcome.IsSuccess()):
    print("GradientSurfaceDataComponent added to entity :SUCCESS")
else:
    raise Exception('FAILURE FATAL: AddComponentsOfType')

components = componentOutcome.GetValue()
tagList = components[0]

pteOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyTreeEditor', tagList)
if(pteOutcome.IsSuccess()):
    pte = pteOutcome.GetValue()
    print("Created a PropertyTreeEditor :SUCCESS")
else:
    raise Exception('FAILURE FATAL: BuildComponentPropertyTreeEditor')

# Test BuildComponentPropertyList
paths = pte.build_paths_list()
for p in paths:
    print('>> {}'.format(p))

tagListPropertyPath = 'm_template|Extended Tags'

print_result('Has a container', is_container(pte, tagListPropertyPath))
print_result('Has zero items', get_container_count(pte, tagListPropertyPath) == 0)
print_result('Add an item 0', add_container_item(pte, tagListPropertyPath, 0, tagOne))
print_result('Has one item 0', get_container_count(pte, tagListPropertyPath) == 1)
print_result('Add an item 1', add_container_item(pte, tagListPropertyPath, 1, tagOne))
print_result('Add an item 2', add_container_item(pte, tagListPropertyPath, 2, tagTwo))
print_result('Add an item 3', add_container_item(pte, tagListPropertyPath, 3, tagThree))
print_result('Has four items', get_container_count(pte, tagListPropertyPath) == 4)
print_result('Updated an item', update_container_item(pte, tagListPropertyPath, 2, tagFour))

itemTag = get_container_item(pte, tagListPropertyPath, 2)
print_result ('itemTag equals tagFour', itemTag.Equal(tagFour))

print_result('Removed one item 0', remove_container_item(pte, tagListPropertyPath, 0))
print_result('Removed one item 1', remove_container_item(pte, tagListPropertyPath, 0))
print_result('Has two items', get_container_count(pte, tagListPropertyPath) == 2)
print_result('Reset items', reset_container(pte, tagListPropertyPath))
print_result('Has cleared the items', get_container_count(pte, tagListPropertyPath) == 0)

# All Done!
editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt')


#!/usr/bin/env python3
"""
Document Description
"""

__author__ = "Dale Anderson"
__version__ = "0.1.0"
__license__ = "GPLv3"

import argparse
from logging.handlers import SysLogHandler
import logging
import sys
import re
# import datetime
# import subprocess
# import boto3
# import re
# from functools import lru_cache

def main():
    handle = open("./input")
    pings = handle.read().split('\n')
    pings = list(filter(None, pings))
    last_ping = None
    increases = 0
    decreases = 0
    for ping in pings:
        log.debug(f'ping {ping}')
        ping = int(ping)
        if last_ping is None:
            last_ping = ping
            continue
        if ping > last_ping:
            increases += 1
        elif ping < last_ping:
            decreases += 1
        last_ping = ping

    print(f'increases: {increases}')

if __name__ == "__main__":
    """ This is executed when run from the command line """
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-v",
        "--verbose",
        action="count",
        default=0,
        help="Verbosity (-v, -vv, etc)")
    args = parser.parse_args()

    # Let terminal operator control the logging level sent to stderr
    levels = [
        logging.WARNING,
        logging.INFO,
        logging.DEBUG,
    ]
    level = levels[min(args.verbose, len(levels) - 1)]

    ##################################
    # DO NOT SET basicConfig.
    # Since we have handlers with individual log levels, using basicConfig will ruin everything.
    ###################################
    # logging.basicConfig()
    #     datefmt='%Y-%m-%d %H:%M:%S',
    # )

    default_date_format = '%Y-%m-%d %H:%M:%S'
    default_log_format = '%(asctime)s.%(msecs)03d %(levelname)s %(module)s/%(funcName)s(): %(message)s'

    # Create our own custom logging configuration. Don't use the built-in automagic stuff.
    log = logging.getLogger("foo")

    # Set the minimum threshold needed by any handler, then override desired levels for each handler.
    # If this is set to "CRITICAL", for instance, nothing will ever appear in any log handler.
    log.setLevel(logging.DEBUG)

    # Set up handler for terminal logging
    console_handler = logging.StreamHandler(sys.stderr)
    console_handler.setLevel(level)  # Let terminal log level be controlled by args
    console_handler.setFormatter(logging.Formatter(default_log_format, datefmt=default_date_format))
    log.addHandler(console_handler)

    # Set up handler for file logging
    file_handler = logging.FileHandler(re.sub(r'\.py$', '', __file__) + '.log')
    file_handler.setLevel(logging.DEBUG)  # Log everything to file
    file_handler.setFormatter(logging.Formatter(default_log_format, datefmt=default_date_format))
    log.addHandler(file_handler)

    # Set up handler for syslog
    syslog_handler = SysLogHandler('/dev/log')
    syslog_handler.setLevel(logging.WARNING)  # Log warnings or worse to syslog
    syslog_handler.setFormatter(logging.Formatter('%(module)s.%(funcName)s[%(process)d] %(levelname)s: %(message)s'))  # Syslog already timestamps everything
    log.addHandler(syslog_handler)

    main()


from Adafruit_LED_Backpack import HT16K33

# Digit value to bitmask mapping:
DIGIT_VALUES = {
    ' ': 0x00,
    '-': 0x40,
    '0': 0x3F,
    '1': 0x06,
    '2': 0x5B,
    '3': 0x4F,
    '4': 0x66,
    '5': 0x6D,
    '6': 0x7D,
    '7': 0x07,
    '8': 0x7F,
    '9': 0x6F,
    'A': 0x77,
    'B': 0x7C,
    'C': 0x39,
    'D': 0x5E,
    'E': 0x79,
    'F': 0x71
}

IDIGIT_VALUES = {
    ' ': 0x00,
    '-': 0x40,
    '0': 0x3F,
    '1': 0x30,
    '2': 0x5B,
    '3': 0x79,
    '4': 0x74,
    '5': 0x6D,
    '6': 0x6F,
    '7': 0x38,
    '8': 0x7F,
    '9': 0x7D,
    'A': 0x7E,
    'B': 0x67,
    'C': 0x0F,
    'D': 0x73,
    'E': 0x4F,
    'F': 0x4E
}

class QuadNumeric(HT16K33.HT16K33):
    """Seven segment 4 digit LED backpack display."""

    def __init__(self, invert=False, **kwargs):
        """Initialize display.  All arguments will be passed to the HT16K33 class
        initializer, including optional I2C address and bus number parameters.
        """
        super(QuadNumeric, self).__init__(**kwargs)
        self.invert = invert

    def set_invert(self, _invert):
        """Set whether the display is upside-down or not.
        """
        self.invert = _invert

    def set_digit_raw(self, pos, bitmask):
        """Set digit at position to raw bitmask value.  Position should be a value
        of 0 to 3 with 0 being the left most digit on the display."""
        if pos < 0 or pos > 3:
            # Ignore out of bounds digits.
            return

        # Calculate the correct position depending on orientation
        if self.invert:
            pos = 3-pos

        # Set the digit bitmask value at the appropriate position.
        self.buffer[pos*2] = bitmask & 0xFF

    def set_digit(self, pos, digit):
        """Set digit at position to provided value.  Position should be a value
        of 0 to 3 with 0 being the left most digit on the display.  Digit should
        be a number 0-9, character A-F, space (all LEDs off), or dash (-).
        """
        if self.invert:
            self.set_digit_raw(pos, IDIGIT_VALUES.get(str(digit).upper(), 0x00))
        else:
            self.set_digit_raw(pos, DIGIT_VALUES.get(str(digit).upper(), 0x00))

    def print_number_str(self, value, justify_right=True):
        """Print a 4 character long string of numeric values to the display.
        Characters in the string should be any supported character by set_digit.
        """
        # Calculate length
        length = len(value)

        # Error if value is longer than 4 characters.
        if length > 4:
            self.print_number_str('----')
            return
        # Calculcate starting position of digits based on justification.
        pos = (4-length) if justify_right else 0
        # Go through each character and print it on the display.
        for i, ch in enumerate(value):
            self.set_digit(pos, ch)
            pos += 1

    def print_float(self, value):
        """Print a numeric value in integer format.
        Value should be from 0 to 9999.
        """
        if not isinstance(value, (int, long, float, complex)):
            # Skip if value is not a number
            return
        if value < 0 or value > 9999:
            # Value out of range
            self.print_number_str('----')
        else:
            # Convert value to int and format to 4 digits
            self.print_number_str("{0:0=4d}".format(int(value)))

    def print_hex(self, value, justify_right=True):
        """Print a numeric value in hexadecimal.  Value should be from 0 to FFFF.
        """
        if value < 0 or value > 0xFFFF:
            # Ignore out of range values.
            return
        self.print_number_str('{0:X}'.format(value), justify_right)


import argparse
import copy
import logging
import logging.config as lconfig
import math
import os
import threading

import flask
from flask import views
from flask import json
import kafka

class LastData():
    def __init__(self):
        self._access_lock = threading.Lock()
        self._data = {
            'last-seen': {},
            'most-positive': {},
            'most-negative': {},
        }

    @staticmethod
    def get_compound_average(sentiments):
        """return the average compound sentiment from a list of sentiments"""
        if len(sentiments) > 0:
            compounds = [s.get('compound', 0) for s in sentiments]
            avg = math.fsum(compounds) / len(sentiments)
        else:
            avg = 0
        return avg

    def update(self, newdata):
        self._access_lock.acquire()
        self._data['last-seen'] = copy.deepcopy(newdata)
        new_cavg = LastData.get_compound_average(
                self._data['last-seen'].get('sentiments', []))
        pos_cavg = LastData.get_compound_average(
                self._data['most-positive'].get('sentiments', []))
        neg_cavg = LastData.get_compound_average(
                self._data['most-negative'].get('sentiments', []))
        if new_cavg >= pos_cavg:
            self._data['most-positive'] = self._data['last-seen']
        if new_cavg <= neg_cavg:
            self._data['most-negative'] = self._data['last-seen']
        self._access_lock.release()

    def copy(self):
        self._access_lock.acquire()
        retval = copy.deepcopy(self._data)
        self._access_lock.release()
        return retval

exit_event = threading.Event()
_last_data = LastData()

def last_data(update=None):
    if update is not None:
        _last_data.update(update)
    return _last_data.copy()

class RootView(views.MethodView):
    def get(self):
        return json.jsonify(last_data())

def consumer(args):
    logging.info('starting kafka consumer')
    consumer = kafka.KafkaConsumer(args.topic, bootstrap_servers=args.brokers)
    for msg in consumer:
        if exit_event.is_set():
            break
        try:
            last_data(json.loads(str(msg.value, 'utf-8')))
        except Exception as e:
            logging.error(e.message)
    logging.info('exiting kafka consumer')

def get_arg(env, default):
    return os.getenv(env) if os.getenv(env, '') is not '' else default

def parse_args(parser):
    args = parser.parse_args()
    args.brokers = get_arg('KAFKA_BROKERS', args.brokers)
    args.topic = get_arg('KAFKA_TOPIC', args.topic)
    return args

def main(args):
    exit_event.clear()
    # setup consumer thread
    cons = threading.Thread(group=None, target=consumer, args=(args,))
    cons.start()

    # create the flask app object
    app = flask.Flask(__name__)
    # change this value for production environments
    app.config['SECRET_KEY'] = 'secret!'
    app.add_url_rule('/', view_func=RootView.as_view('index'))
    app.run(host='0.0.0.0', port=8080)

    exit_event.set()
    cons.join()
    logging.info('exiting flask-kafka-listener')

if __name__ == '__main__':
    lconfig.dictConfig({
        'version': 1,
        'formatters': {'default': {
            'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
            }},
        'handlers': {'wsgi': {
            'class': 'logging.StreamHandler',
            'stream': 'ext://flask.logging.wsgi_errors_stream',
            'formatter': 'default'
            }},
        'root': {
            'level': 'INFO',
            'handlers': ['wsgi']
            }
        })
    logging.basicConfig(level=logging.INFO)
    logging.info('starting update-visualizer')
    parser = argparse.ArgumentParser(
            description='listen for some stuff on kafka')
    parser.add_argument(
            '--brokers',
            help='The bootstrap servers, env variable KAFKA_BROKERS',
            default='kafka.kafka.svc:9092')
    parser.add_argument(
            '--topic',
            help='Topic to publish to, env variable KAFKA_TOPIC',
            default='social-firehose')
    args = parse_args(parser)
    main(args)
    logging.info('exiting')


# -*- coding:utf-8 -*-
import pyautogui
import pydirectinput
import time

screenWidth, screenHeight = pydirectinput.size() # Get the size of the primary monitor.
currentMouseX, currentMouseY = pydirectinput.position() # Get the XY position of the mouse.
print(screenWidth,screenHeight,currentMouseX,currentMouseY)
'''
ox , oy = pydirectinput.position()
while 1:
    if (ox,oy) != pydirectinput.position():
        ox, oy = pydirectinput.position()
        print(ox, oy)
'''

for i in range(2,-1,-1): #倒數3秒
    print(i)
    time.sleep(1)

cnt = 0
'''
for pos in pydirectinput.locateAllOnScreen('./clock.png'):
    print(pos)
    cnt += 1

if cnt == 0: print('There was nothing matched.')
'''
'''
for i in range(5):
    #pydirectinput.click(x = d[0], y = d[1])
    pydirectinput.mouseDown(x=d[0], y=d[1], button='left')
    time.sleep(0.1)
    pydirectinput.mouseUp(x=d[0], y=d[1], button='left')
    time.sleep(0.3)
'''
'''
for pos in pyautogui.locateAllOnScreen('./ScreenShots/test.png', grayscale=True):
    print(pos)
'''

'''
pos = pyautogui.locateOnScreen('./ScreenShots/clock.png')
print(pos)
'''
'''
t1 = time.time()
time.sleep(0.2)
t2 = time.time()
print(t2-t1)
'''
pydirectinput.press('1')


def select(self, path, feather=True):

        """Applies the polygonal lasso tool on a layer.

        The path paramater is a list of points,
        either [x1, y1, x2, y2, x3, y3, ...]
        or [(x1,y1), (x2,y2), (x3,y3), ...]

        The parts of the layer that fall outside
        this polygonal area are cut.

        The selection is not anti-aliased,
        but the feather parameter creates soft edges.

        """

        w, h = self.img.size
        mask = Image.new("L", (w,h), 0)
        draw = ImageDraw.Draw(mask)

        draw = ImageDraw.Draw(mask)
        draw.polygon(path, fill=255)

        if feather:
            mask = mask.filter(ImageFilter.SMOOTH_MORE)
            mask = mask.filter(ImageFilter.SMOOTH_MORE)

        mask = ImageChops.darker(mask, self.img.split()[3])
        self.img.putalpha(mask)


from pathlib import Path

from setuptools import setup

requirements = Path(__file__).parent / 'requirements.txt'

with requirements.open(mode='rt', encoding='utf-8') as fp:
    install_requires = [line.strip() for line in fp]

readme = Path(__file__).parent / 'README.rst'

with readme.open(mode='rt', encoding='utf-8') as fp:
    readme_text = fp.read()

VERSION = '0.0.1'

setup(
    name='numerical_algorithms',
    maintainer='Luka Shostenko',
    maintainer_email='luka.shostenko@gmail.com',
    version='{version}'.format(
        version=VERSION,
    ),
    download_url='https://github.com/LShostenko/numerical_algorithms/archive/{version}.tar.gz'.format(  # noqa
        version=VERSION,
    ),
    description='Optimized numerical routines.',
    long_description=readme_text,
    license='Apache License 2.0',
    author='Luka Shostenko',
    author_email='luka.shostenko@gmail.com',
    packages=['numerical_algorithms'],
    python_requires='>=3.5.0',
    install_requires=install_requires,
    include_package_data=True,
)


import os
import threading
from time import sleep

from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
from watchdog.observers.polling import PollingObserver
from config import RMT_MEDIAEXT, SYNC_DIR_CONFIG, Config
import log
from rmt.filetransfer import FileTransfer
from utils.functions import get_dir_files_by_ext, singleton
from utils.types import SyncType

lock = threading.Lock()

@singleton
class Sync(object):
    filetransfer = None
    __observer = []
    __sync_path = None
    __sync_sys = "Linux"
    __config = None
    __synced_files = []
    __need_sync_paths = {}

    def __init__(self):
        self.filetransfer = FileTransfer()
        self.__config = Config()
        app = self.__config.get_config('app')
        if app:
            self.__sync_sys = app.get('nas_sys', "Linux")
        sync = self.__config.get_config('sync')
        if sync:
            self.__sync_path = sync.get('sync_path')

    # 处理文件变化
    def file_change_handler(self, event, text, event_path):
        if not event.is_directory:
            # 文件发生变化
            try:
                # 目的目录的子文件不处理
                for tpath in SYNC_DIR_CONFIG.values():
                    if tpath:
                        if tpath in event_path:
                            return
                        if os.path.samefile(event_path, tpath):
                            return
                # 回收站及隐藏的文件不处理
                if event_path.find('/@Recycle/') != -1 or event_path.find('/#recycle/') != -1 or event_path.find(
                        '/.') != -1:
                    return False
                # 文件名
                name = os.path.basename(event_path)
                if not name:
                    return
                # 判断是不是媒体文件
                ext = os.path.splitext(name)[-1]
                if ext not in RMT_MEDIAEXT:
                    return
                # 判断是否处理过了
                need_handler_flag = False
                try:
                    lock.acquire()
                    if event_path not in self.__synced_files:
                        self.__synced_files.append(event_path)
                        need_handler_flag = True
                finally:
                    lock.release()

                if not need_handler_flag:
                    log.debug("【SYNC】文件已处理过：%s" % event_path)
                    return

                log.info("【SYNC】文件%s：%s" % (text, event_path))
                # 找到是哪个监控目录下的
                monitor_dir = event_path
                from_dir = os.path.dirname(event_path)
                is_root_path = False
                for m_path in SYNC_DIR_CONFIG.keys():
                    if m_path in event_path:
                        monitor_dir = m_path
                    if os.path.samefile(m_path, from_dir):
                        is_root_path = True

                # 查找目的目录
                target_dir = SYNC_DIR_CONFIG.get(monitor_dir)
                # 监控根目录下的文件发生变化时直接发走
                if is_root_path:
                    self.filetransfer.transfer_media(in_from=SyncType.MON,
                                                     in_path=event_path,
                                                     target_dir=target_dir)
                else:
                    try:
                        lock.acquire()
                        if self.__need_sync_paths.get(from_dir):
                            files = self.__need_sync_paths.get('files')
                            if not files:
                                files = [event_path]
                            else:
                                if event_path not in files:
                                    files.append(event_path)
                                else:
                                    return
                            self.__need_sync_paths[from_dir].update({'files': files})
                        else:
                            self.__need_sync_paths[from_dir] = {'target_dir': target_dir, 'files': [event_path]}
                    finally:
                        lock.release()

            except Exception as e:
                log.error("【SYNC】发生错误：%s" % str(e))
        else:
            # 文件变化时上级文件夹也会变化
            # 目的目录的子文件不处理
            for tpath in SYNC_DIR_CONFIG.values():
                if tpath:
                    if tpath in event_path:
                        return
                    if os.path.samefile(event_path, tpath):
                        return
            # 源目录本身或上级目录不处理
            for tpath in SYNC_DIR_CONFIG.keys():
                if event_path in tpath:
                    return
                if os.path.samefile(event_path, tpath):
                    return
            # 回收站及隐藏的文件不处理
            if event_path.find('/@Recycle') != -1 or event_path.find('/#recycle') != -1 or event_path.find('/.') != -1:
                return False
            # 开始处理变化，等10秒钟，让文件充分变化
            sleep(10)
            try:
                lock.acquire()
                sync_item = self.__need_sync_paths.get(event_path)
                if sync_item:
                    sync_len = len(sync_item.get('files'))
                    file_len = len(get_dir_files_by_ext(event_path, RMT_MEDIAEXT))
                    if sync_len >= file_len:
                        # 该目录下所有的文件都发生了改变，发走
                        self.filetransfer.transfer_media(in_from=SyncType.MON,
                                                         in_path=event_path,
                                                         target_dir=sync_item.get('target_dir'))
                        del self.__need_sync_paths[event_path]
            finally:
                lock.release()

    # 批量转移文件
    def transfer_mon_files(self, no_path=None):
        try:
            lock.acquire()
            items = self.__need_sync_paths.items()
            for path, item in items:
                if path == no_path:
                    continue
                log.info("【SYNC】开始转移监控目录文件...")
                self.filetransfer.transfer_media(in_from=SyncType.MON,
                                                 in_path=path,
                                                 target_dir=item.get('target_dir'))
                del self.__need_sync_paths[path]
        finally:
            lock.release()

    # 启动进程
    def run_service(self):
        # Sync监控转移
        if self.__sync_path:
            for sync_monpath in self.__sync_path:
                # 目录是两段式，需要把配对关系存起来
                if sync_monpath.find('|') != -1:
                    # 源目录|目的目录，这个格式的目的目录在源目录同级建立
                    monpath = sync_monpath.split("|")[0]
                    target_path = sync_monpath.split("|")[1]
                    if target_path:
                        log.info("【SYNC】读取到监控目录：%s，目的目录：%s" % (monpath, target_path))
                        if not os.path.exists(target_path):
                            log.info("【SYNC】目的目录不存在，正在创建：%s" % target_path)
                            os.makedirs(target_path)
                        # 去掉末尾的/
                        if monpath.endswith('/'):
                            monpath = monpath[0:-1]
                        SYNC_DIR_CONFIG[monpath] = target_path
                else:
                    monpath = sync_monpath
                    SYNC_DIR_CONFIG[monpath] = None
                    log.info("【SYNC】读取监控目录：%s" % monpath)

                if os.path.exists(monpath):
                    if self.__sync_sys == "Linux":
                        # linux
                        observer = Observer()
                    else:
                        # 其他
                        observer = PollingObserver()
                    self.__observer.append(observer)

                    observer.schedule(FileMonitorHandler(monpath, self), path=monpath, recursive=True)
                    observer.setDaemon(False)
                    observer.start()
                    log.info("【RUN】%s 的monitor.media_sync启动..." % monpath)
                else:
                    log.error("【SYNC】%s 目录不存在！" % sync_monpath)

    # 关闭服务
    def stop_service(self):
        if self.__observer:
            for observer in self.__observer:
                observer.stop()

# 监听文件夹
class FileMonitorHandler(FileSystemEventHandler):
    sync = None

    def __init__(self, monpath, sync, **kwargs):
        super(FileMonitorHandler, self).__init__(**kwargs)
        # 监控目录 目录下面以device_id为目录存放各自的图片
        self._watch_path = monpath
        self.sync = sync

    # 重写文件创建函数，文件创建都会触发文件夹变化
    def on_created(self, event):
        self.sync.file_change_handler(event, "创建", event.src_path)

    def on_moved(self, event):
        self.sync.file_change_handler(event, "移动", event.dest_path)

    def on_modified(self, event):
        self.sync.file_change_handler(event, "修改", event.src_path)


import unittest #make unit testing framework for python available
import GeometryCalcWeb as app

class TestWeb(unittest.TestCase):

	def setUp(self):
		app.app.testing = True
		self.app = app.app.test_client()
	#Test the index.html page
	def test_index(self):
		rv = self.app.get('/')
		self.assertEqual(rv.status, '200 OK')

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


import logging

from .ApiBase import ApiBase

logger = logging.getLogger(__name__)

class LeaderboardRatingApiConnector(ApiBase):
    def __init__(self, dispatch, leaderboardName):
        ApiBase.__init__(self, '/data/leaderboardRating')
        self.dispatch = dispatch
        self.leadeboardName = leaderboardName

    def requestData(self, queryDict={}):
        self.request(queryDict, self.handleData)

    def handleData(self, message, meta):
        preparedData = dict(
            command='stats',
            type='leaderboardRating',
            leaderboardName=self.leadeboardName,
            values=message,
            meta=meta['meta'],
        )
        self.dispatch.dispatch(preparedData)

class LeaderboardApiConnector(ApiBase):
    def __init__(self, dispatch):
        ApiBase.__init__(self, '/data/leaderboard')
        self.dispatch = dispatch

    def requestData(self, queryDict={}):
        self.request(queryDict, self.handleData)

    def handleData(self, message):
        preparedData = dict(
            command='stats',
            type='leaderboard',
            values=message,
        )
        self.dispatch.dispatch(preparedData)


import copy
import numpy as np
import pandas as pd
from biztax.years import START_YEAR, END_YEAR, NUM_YEARS
from biztax.data import Data
from biztax.asset import Asset
from biztax.debt import Debt
from biztax.corptaxreturn import CorpTaxReturn
from biztax.response import Response
from biztax.domesticmne import DomesticMNE

class Corporation():
    """
    Constructor for the Corporation class.
    This contains both the real and tax information relevant to the
    corporate income tax.
    """

    def __init__(self, btax_params):
        # Store policy parameter objects
        if isinstance(btax_params, pd.DataFrame):
            self.btax_params = btax_params
        else:
            raise ValueError('btax_params must be DataFrame')
        # Create Data object
        self.data = Data()
        # Create Asset object and calculate
        self.asset = Asset(self.btax_params, corp=True, data=self.data)
        self.asset.calc_all()
        # Create DomesticMNE object
        self.dmne = DomesticMNE(self.btax_params)
        self.dmne.calc_all()
        # Create earnings forecast
        self.create_earnings()

    def create_debt(self):
        """
        Creates the Debt object for the Corporation.
        Note: create_asset must have already been called
        """
        self.debt = Debt(self.btax_params, self.asset.get_forecast(),
                         data=self.data, corp=True)
        self.debt.calc_all()

    def create_earnings(self):
        """
        Creates the initial forecast for earnings. Static only.
        """
        # Grab forecasts of profit growth
        earnings_forecast = np.asarray(self.data.gfactors['profit'])
        gfacts = earnings_forecast[1:] / earnings_forecast[0]
        # 2013 values for non-modeled revenues
        taxitems = np.array(self.data.corp_tax2013['ALL'])
        receipts = taxitems[4] * gfacts
        rent_inc = taxitems[7] * gfacts
        royalties = taxitems[8] * gfacts
        capgains = (taxitems[9] + taxitems[10] + taxitems[11] - taxitems[32]) * gfacts
        domestic_divs = taxitems[12] * gfacts
        other_recs = taxitems[14] * gfacts
        # 2013 values for non-modeled deductions and credits
        cogs = taxitems[16] * gfacts
        execcomp = taxitems[17] * gfacts
        wages = taxitems[18] * gfacts
        repairs = taxitems[19] * gfacts
        baddebt = taxitems[20] * gfacts
        rent_paid = taxitems[21] * gfacts
        statelocaltax = taxitems[22] * gfacts
        charity = taxitems[24] * gfacts
        amortization = taxitems[25] * gfacts
        depletion = taxitems[27] * gfacts
        advertising = taxitems[28] * gfacts
        pensions = taxitems[29] * gfacts
        benefits = taxitems[30] * gfacts
        sec199_base = taxitems[31] * gfacts
        other_ded = taxitems[33] * gfacts
        gbc = taxitems[42] * gfacts
        # Save unodeled tax items
        self.revenues = pd.DataFrame({'year': range(START_YEAR, END_YEAR + 1),
                                      'receipts': receipts,
                                      'rent': rent_inc,
                                      'royalties': royalties,
                                      'capgains': capgains,
                                      'domestic_divs': domestic_divs,
                                      'other': other_recs})
        self.deductions = pd.DataFrame({'year': range(START_YEAR, END_YEAR + 1),
                                        'cogs': cogs,
                                        'execcomp': execcomp,
                                        'wages': wages,
                                        'repairs': repairs,
                                        'baddebt': baddebt,
                                        'rent': rent_paid,
                                        'statelocaltax': statelocaltax,
                                        'charity': charity,
                                        'amortization': amortization,
                                        'depletion': depletion,
                                        'advertising': advertising,
                                        'pensions': pensions,
                                        'benefits': benefits,
                                        'sec199share': sec199_base,
                                        'other': other_ded})
        self.credits = pd.DataFrame({'year': range(START_YEAR, END_YEAR + 1),
                                     'gbc': gbc})

    def file_taxes(self):
        """
        Creates the CorpTaxReturn object.
        """
        self.taxreturn = CorpTaxReturn(self.btax_params, self.revenues,
                                       self.deductions, self.credits,
                                       dmne=self.dmne, data=self.data,
                                       assets=self.asset, debts=self.debt)
        self.taxreturn.calc_all()

    def real_activity(self):
        """
        Produces a DataFrame of the corporation's real activity.
        Real measures are:
            Capital stock
            Investment
            Depreciation (economic)
            Net debt
            Net interest paid
            Earnings
            Tax liability
            Net income
            Cash flow
        """

        real_results = pd.DataFrame({'year': range(START_YEAR, END_YEAR + 1)})
        real_results['Earnings'] = (self.revenues['receipts']
                                    + self.revenues['rent']
                                    + self.revenues['royalties']
                                    + self.revenues['capgains']
                                    + self.revenues['domestic_divs']
                                    + self.revenues['other']
                                    - self.deductions['cogs']
                                    - self.deductions['execcomp']
                                    - self.deductions['wages']
                                    - self.deductions['repairs']
                                    - self.deductions['baddebt']
                                    - self.deductions['rent']
                                    - self.deductions['charity']
                                    - self.deductions['depletion']
                                    - self.deductions['advertising']
                                    - self.deductions['pensions']
                                    - self.deductions['benefits']
                                    - self.deductions['other']
                                    + self.dmne.dmne_results['foreign_directinc']
                                    + self.dmne.dmne_results['foreign_indirectinc'])
        real_results['Kstock'] = self.asset.get_forecast()
        real_results['Inv'] = self.asset.get_investment()
        real_results['Depr'] = self.asset.get_truedep()
        real_results['Debt'] = self.debt.get_debt()
        real_results['NIP'] = self.debt.get_nip()
        real_results['Tax'] = self.taxreturn.get_tax()
        real_results['NetInc'] = (real_results['Earnings']
                                  - real_results['Depr']
                                  - real_results['NIP']
                                  - real_results['Tax']
                                  - self.dmne.dmne_results['foreign_tax']
                                  - self.deductions['statelocaltax'])
        real_results['CashFlow'] = (real_results['Earnings']
                                    - real_results['Inv']
                                    - real_results['Tax']
                                    - self.dmne.dmne_results['foreign_tax']
                                    - self.deductions['statelocaltax'])
        self.real_results = real_results

    def calc_static(self):
        """
        Runs the static calculations.
        """
        self.create_debt()
        self.file_taxes()
        self.real_activity()

    def update_legal(self, responses):
        """
        Updates the rescale_corp and rescale_noncorp associated with each
        Data associated with each object.
        """
        self.data.update_rescaling(responses.rescale_corp,
                                   responses.rescale_noncorp)
        self.asset.data.update_rescaling(responses.rescale_corp,
                                         responses.rescale_noncorp)

    def update_investment(self, responses):
        """
        Updates the Asset object to include investment response.
        """
        # First, save the capital stock by asset type and year (for earnings)
        self.old_capital_history = copy.deepcopy(self.asset.capital_history)
        self.asset.update_response(responses.investment_response)
        self.asset.calc_all()

    def update_repatriation(self, responses):
        """
        Updates the DomesticMNE object to include the repatriation response.
        Also updates profits to reflect this response.
        """
        # First, save current foreign earnings
        self.dmne.update_profits(responses.repatriation_response,
                                 responses.shifting_response)
        self.dmne.calc_all()

    def update_earnings(self, responses):
        """
        Recalculates earnings using the old capital stock by asset type, the
        new capital stock by asset type (based on the investment response),
        and the marginal product of capital.
        """
        Kstock_base = copy.deepcopy(self.old_capital_history)
        Kstock_ref = copy.deepcopy(self.asset.capital_history)
        changeEarnings = np.zeros((95, NUM_YEARS))
        for iyr in range(NUM_YEARS):  # for each year
            ystr = str(iyr + START_YEAR)
            mpk = np.array(responses.investment_response['MPKc' + ystr])
            for i in range(95):  # by asset
                changeEarnings[i, iyr] = (Kstock_ref[ystr][i] -
                                          Kstock_base[ystr][i]) * mpk[i]
        deltaE = np.zeros(NUM_YEARS)
        for iyr in range(NUM_YEARS):
            deltaE[iyr] = changeEarnings[:, iyr].sum()
        # Update new earnings
        self.revenues['receipts'] = self.revenues['receipts'] + deltaE

    def update_debt(self, responses):
        """
        Replaces the Debt object to use the new asset forecast and Data
        """
        pctch_delta = np.array(responses.debt_response['pchDelta_corp'])
        self.debt = Debt(self.btax_params, self.asset.get_forecast(),
                         data=self.data, response=pctch_delta, corp=True)
        self.debt.calc_all()

    def apply_responses(self, responses):
        """
        Updates Data, Asset, earnings, Debt and CorpTaxReturn to include
        responses. Then calc_all() for each object.
        """
        assert isinstance(responses, Response)
        self.update_legal(responses)
        self.update_investment(responses)
        self.update_repatriation(responses)
        self.update_earnings(responses)
        self.update_debt(responses)
        self.file_taxes()
        self.real_activity()

    def get_netinc(self):
        """
        Returns an array of the corporation's net income (after-tax).
        """
        netinc = np.array(self.real_results['NetInc'])
        return netinc

    def get_taxrev(self):
        """
        Returns an array of the corporation's tax liability.
        """
        taxrev = np.array(self.real_results['Tax'])
        return taxrev


import sys
from yamlSupport.YamlConfigurationSupport import YamlConfigurationSupport
from googleSheetSupport.GoogleSheetSupport import GoogleSheetSupport
from iosSupport.iOSLocalizationSettings import iOSLocalizationSettings

def log_menu():
    menu = """commands:\n1. cnfg - create default localization.yml\n2. fetch - fetch localization"""
    print(menu)

if __name__ == '__main__':
    args = sys.argv
    if len(args) < 2:
        log_menu()
    elif args[1] == "cnfg":
        YamlConfigurationSupport.create_default()
    elif args[1] == "fetch":
        config = YamlConfigurationSupport.get_config()
        localizations = GoogleSheetSupport.get_localizations()
        iOSLocalizationSettings.create(localizations, config)
    else:
        log_menu()


from .serializers import GradeSerializer, ParentSerializer, SemesterSerializer
from .models import Grade, Parent, Semester
from .serializers import UserSerializer
from .models import User
from django.shortcuts import get_list_or_404, get_object_or_404
from rest_framework import generics, permissions

# Create your views here.

class UserCreate(generics.CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [permissions.AllowAny]

class GetUser(generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_object(self):
        queryset = self.get_queryset()
        filter = {'username': self.request.user.username}
        obj = get_object_or_404(queryset, **filter)
        self.check_object_permissions(self.request, obj)
        obj.password = ""
        return obj

class GradesListCreate(generics.ListCreateAPIView):
    queryset = Grade.objects.all()
    serializer_class = GradeSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        userid = User.objects.get(
            username=self.request.user.username).id
        return get_list_or_404(Grade.objects.filter(user_id=userid))

class SemesterListCreate(generics.ListCreateAPIView):
    queryset = Semester.objects.all()
    serializer_class = SemesterSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        userid = User.objects.get(
            username=self.request.user.username).id
        return get_list_or_404(Grade.objects.filter(user_id=userid))

class ParentListCreate(generics.ListCreateAPIView):
    queryset = Parent.objects.all()
    serializer_class = ParentSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        userid = User.objects.get(
            username=self.request.user.username).id
        return get_list_or_404(Grade.objects.filter(user_id=userid))


import xml.etree.ElementTree as ET
import uuid
import httplib
import logging
import json
import urlparse
import boto.s3 as s3

import s3etag
import common

logger = logging.getLogger('httpxml_to_s3')

def httpxml_to_s3(http_url,
                  s3_url,
                  region='eu-west-1',
                  profile_name=None,
                  xml_preprocessor=lambda s: s):
    def inner(fn_inner):
        return sync_to_bucket(s3_url, region, profile_name)(from_xml(http_url)(fn_inner))
    return inner;

def sync_to_bucket(s3_url,
                   region='eu-west-1',
                   profile_name=None):
    """
    Decorator function configuring function
    xml_preprocessor - If some preprocessing needs to be done on the xml as
                       a string a lambda can be sent in. Defaults to the
                       identity function
    """

    parsed_s3_url = urlparse.urlparse(s3_url);

    bucket_name = parsed_s3_url.hostname;
    key_prefix = parsed_s3_url.path;
    if key_prefix[0] == '/':
        key_prefix = key_prefix[1:]
    if key_prefix[-1] != '/':
        key_prefix = key_prefix + '/'

    def inner(fn_inner):
        """
        Decorator function function sent in should be having signature
        func(None,None, XmlDoc) and should yield JSON document one for
        each file that should be persisted to S3
        """

        def handler(event, context):
            """
            The AWS Lambda Entry Point
            """
            s3conn = s3.connect_to_region(region, profile_name=profile_name)
            bucket = s3conn.get_bucket(bucket_name)

            # Use a map to track keys that are no longer in the feed, used for deletion
            remaining_keys = { key.name : True for key in bucket.list(prefix=key_prefix)}

            logger.debug("Existing keys in bucket\n%s", '\n'.join(remaining_keys));

            for id, json_data in fn_inner():
                key_name = key_prefix + str(uuid.uuid5(uuid.NAMESPACE_URL, id.encode('utf-8')))

                # Key found, delete it from cleanup map
                if key_name in remaining_keys:
                    del remaining_keys[key_name]

                string_data = json.dumps(json_data)
                s3_object = bucket.get_key(key_name)
                if s3_object == None:
                    key = bucket.new_key(key_name);
                    key.set_contents_from_string(string_data)
                    logger.info('Creating:\ts3://%s/%s', bucket_name, key_name)
                    logger.debug(string_data)
                else:
                    if s3_object.etag[1:len(s3_object.etag)-1] != s3etag.from_string(string_data):
                        logger.info('Updating:\ts3://%s/%s', bucket_name, key_name)
                        logger.debug(string_data)
                        s3_object.set_contents_from_string(string_data)
                    else:
                        logger.info('Same:\ts3://%s/%s', bucket_name, key_name);
                        logger.debug(string_data)

            # Remvoe remaining keys from the bucket to allow for cleanup
            for key in remaining_keys:
                logger.info('Removing:\ts3://%s/%s', bucket_name, key);
                bucket.delete_key(key);

            logger.info('Done');

        return handler

    return inner

def from_xml(url):
    def inner(fn_inner):
        def handler():
            input_xml = ET.fromstring(common.get_page(url))
            return fn_inner(input_xml)
        return handler
    return inner


import os
import re
import base64
import shutil
import platform
import html

from PIL import Image
from pathlib import Path
from textwrap import dedent
from datetime import datetime
from xml.etree import ElementTree as ET
from pkg_resources import resource_filename
from ipykernel.kernelbase import Kernel

from .config import config
from .completions import CompletionsManager
from .code_manager import CodeManager
from .stata_session import StataSession
from .stata_magics import StataMagics

class StataKernel(Kernel):
    implementation = 'stata_kernel'
    implementation_version = '1.13.0'
    language = 'stata'
    language_info = {
        'name': 'stata',
        'mimetype': 'text/x-stata',
        'codemirror_mode': 'stata',
        'file_extension': '.do',
        'version': '15.1'}
    help_links = [
        {'text': 'stata_kernel Help', 'url': 'https://kylebarron.dev/stata_kernel/'},
        {'text': 'Stata Help', 'url': 'https://www.stata.com/features/documentation/'}
    ]  # yapf: disable

    def __init__(self, *args, **kwargs):
        # Copy syntax highlighting files
        from_paths = [
            Path(resource_filename('stata_kernel', 'pygments/stata.py')),
            Path(resource_filename('stata_kernel', 'codemirror/stata.js'))]
        to_paths = [
            Path(resource_filename('pygments', 'lexers/stata.py')),
            Path(
                resource_filename(
                    'notebook',
                    'static/components/codemirror/mode/stata/stata.js'))]

        for from_path, to_path in zip(from_paths, to_paths):
            copy = False
            if to_path.is_file():
                to_path_dt = datetime.fromtimestamp(to_path.stat().st_mtime)
                from_path_dt = datetime.fromtimestamp(from_path.stat().st_mtime)
                if from_path_dt > to_path_dt:
                    copy = True
            else:
                copy = True

            if copy:
                try:
                    to_path.parents[0].mkdir(parents=True, exist_ok=True)
                    shutil.copy(str(from_path), str(to_path))
                except OSError:
                    pass

        super(StataKernel, self).__init__(*args, **kwargs)

        self.graph_formats = ['svg', 'png', 'pdf', 'eps']
        self.sc_delimit_mode = False
        self.stata = StataSession(self)
        self.banner = self.stata.banner
        self.language_version = self.stata.stata_version
        self.magics = StataMagics(self)
        self.completions = CompletionsManager(self)
        self.quickdo('cap di "Set _rc to 0 initially"')

    def do_execute(
            self, code, silent, store_history=True, user_expressions=None,
            allow_stdin=False):
        """Execute user code.

        This is the function that Jupyter calls to run code. Must return a
        dictionary as described here:
        https://jupyter-client.readthedocs.io/en/stable/messaging.html#execution-results
        """
        invalid_input_msg = """\
        stata_kernel error: code entered was incomplete.

        This usually means that a loop or program was not correctly terminated.
        This can also happen if you are in `#delimit ;` mode and did not end the
        command with `;`. Use `%delimit` to see the current delimiter mode and
        use `#delimit cr` to switch back to the default mode where `;` is
        unnecessary.
        """
        if not self.is_complete(code):
            self.send_response(
                self.iopub_socket, 'stream', {
                    'text': dedent(invalid_input_msg),
                    'name': 'stderr'})

            return {
                'status': 'error',
                'ename': 'error_exception_name',
                'evalue': 'exception_value',
                'traceback': [''],
                'execution_count': self.execution_count}

        # Search for magics in the code
        code = self.magics.magic(code, self)

        # If the magic executed, bail out early
        if self.magics.quit_early:
            return self.magics.quit_early

        # Tokenize code and return code chunks
        cm = CodeManager(code, self.sc_delimit_mode, self.stata.mata_mode)
        self.stata._mata_refresh(cm)
        text_to_run, md5, text_to_exclude = cm.get_text(self.stata)

        # Execute code chunk
        rc, res = self.stata.do(
            text_to_run, md5, text_to_exclude=text_to_exclude)
        res = self.stata._mata_restart(rc, res)

        # Post magic results, if applicable
        self.magics.post(self)
        self.post_do_hook()

        # Alert if delimiter changed. NOTE: This compares the delimiter at the
        # end of the code block with that at the end of the previous code block.
        if (not silent) and (cm.ends_sc != self.sc_delimit_mode):
            delim = ';' if cm.ends_sc else 'cr'
            self.send_response(
                self.iopub_socket, 'stream', {
                    'text': 'delimiter now {}'.format(delim),
                    'name': 'stdout'})
        self.sc_delimit_mode = cm.ends_sc

        # The base class increments the execution count
        return_obj = {'execution_count': self.execution_count}
        if rc:
            return_obj['status'] = 'error'
            return_obj['ename'] = 'error_exception_name'
            return_obj['evalue'] = 'exception_value'
            return_obj['traceback'] = ['']
        else:
            return_obj['status'] = 'ok'
            return_obj['payload'] = []
            return_obj['user_expressions'] = {}
        return return_obj

    def post_do_hook(self):
        """Things to do after running commands in Stata
        """

        store_rc = """\
        tempname __user_rc
        local `__user_rc' = _rc
        """
        self.quickdo(dedent(store_rc))
        _rc, _res = self.cleanLogs("off")

        self.stata.linesize = int(self.quickdo("di `c(linesize)'"))
        self.stata.cwd = self.quickdo("pwd")
        self.completions.refresh(self)

        _rc, _res = self.cleanLogs("on")

        # Restore _rc
        restore_rc = """\
        _StataKernelResetRC, num(``__user_rc'')
        macro drop _`__user_rc'
        macro drop ___user_rc
        """
        self.quickdo(dedent(restore_rc))

    def quickdo(self, code):
        code = self.stata._mata_escape(code)
        cm = CodeManager(code)
        text_to_run, md5, text_to_exclude = cm.get_text()
        rc, res = self.stata.do(
            text_to_run, md5, text_to_exclude=text_to_exclude, display=False)

        if not rc:
            # Remove rmsg lines when rmsg is on
            rmsg_regex = r'r(\(\d+\))?;\s+t=\d*\.\d*\s*\d*:\d*:\d*'
            res = [
                x for x in res.split('\n')
                if not re.search(rmsg_regex, x.strip())]
            res = '\n'.join(res).strip()
            if self.stata.mata_open:
                res = re.sub(
                    r'^([:\>])  ??(\{\})?$', '', res,
                    flags=re.MULTILINE).strip()

            return res

    def cleanLogs(self, what):
        code = self.stata._mata_escape("_StataKernelLog {0}".format(what))
        cm = CodeManager(code)
        text_to_run, md5, text_to_exclude = cm.get_text()
        rc, res = self.stata.do(
            text_to_run, md5, text_to_exclude=text_to_exclude, display=False)

        if what == 'off':
            code = self.stata._mata_escape('_StataKernelLog {0}'.format(what))
            self.cleanTail(code, self.stata.prompt_dot)
        return rc, res

    def send_image(self, graph_paths):
        """Load graph and send to frontend

        This supports SVG, PNG, and PDF formats. While PDF display isn't
        supported in Atom or Jupyter, the data can be stored within the Jupyter
        Notebook file and makes exporting images to PDF through LaTeX easier.

        Args:
            graph_paths (List[str]): path to exported graph
        """

        no_display_msg = 'This front-end cannot display the desired image type.'
        content = {'data': {'text/plain': no_display_msg}, 'metadata': {}}
        warn = False
        for graph_path in graph_paths:
            file_size = Path(graph_path).stat().st_size
            if (file_size > 2 * (1024 ** 3)) & (len(graph_paths) >= 2):
                warn = True

            # run user-specified eps convert, if available
            graph_epstopng = False
            graph_epstopdf = False
            if graph_path.endswith('.eps'):
                epstopdf_program = config.get('graph_epstopdf_program')
                epstopng_program = config.get('graph_epstopng_program')
                if epstopng_program:
                    base_path = graph_path
                    graph_path = Path(graph_path).with_suffix('.png')
                    os.system(epstopng_program.format(base_path, graph_path))
                    graph_epstopng = True
                elif epstopdf_program:
                    base_path = graph_path
                    graph_path = Path(graph_path).with_suffix('.pdf')
                    os.system(epstopdf_program.format(base_path, graph_path))
                    graph_epstopdf = True
                else:
                    graph_path = Path(graph_path)
            else:
                graph_path = Path(graph_path)

            # display graph in front-end
            if graph_path.suffix == '.svg':
                with graph_path.open('r', encoding='utf-8') as f:
                    img = f.read()
                e = ET.ElementTree(ET.fromstring(img))
                root = e.getroot()

                width = int(root.attrib['width'][:-2])
                height = int(root.attrib['height'][:-2])
                # Wrap SVG in iframe. See #234.
                iframe = """\
                <iframe frameborder="0" scrolling="no" height="{0}" width="{1}"\
                srcdoc="{2}">
                """.format(height, width, html.escape(img))
                content['data']['text/html'] = dedent(iframe)
                content['metadata']['text/html'] = {
                    'width': width,
                    'height': height}

                content['data']['image/svg+xml'] = img
                content['metadata']['image/svg+xml'] = {
                    'width': int(root.attrib['width'][:-2]),
                    'height': int(root.attrib['height'][:-2])}

            elif graph_path.suffix == '.png' or graph_epstopng:
                im = Image.open(graph_path)
                width = im.size[0]
                height = im.size[1]

                # On my Mac, the width is double what I told Stata to export.
                # This is not true on my Windows test VM
                if platform.system() == 'Darwin':
                    width /= 2
                    height /= 2
                with graph_path.open('rb') as f:
                    img = base64.b64encode(f.read()).decode('utf-8')

                content['data']['image/png'] = img
                content['metadata']['image/png'] = {
                    'width': width,
                    'height': height}

            elif graph_path.suffix == '.pdf' or graph_epstopdf:
                with graph_path.open('rb') as f:
                    pdf = base64.b64encode(f.read()).decode('utf-8')
                content['data']['application/pdf'] = pdf

            elif graph_path.suffix == '.eps':
                with graph_path.open('rb') as f:
                    eps = base64.b64encode(f.read()).decode('utf-8')
                content['data']['application/eps'] = eps

        msg = """\
        **`stata_kernel` Warning**: One of your image files is larger than 2MB
        and you have Graph Redundancy on. If you don't plan to export the
        Jupyter Notebook file to PDF, you can save space by running:

        ```
        %set graph_svg_redundancy false [--permanently]
        %set graph_png_redundancy false [--permanently]
        ```

        To turn off this warning, run:

        ```
        %set graph_redundancy_warning false [--permanently]
        ```

        For more information, see:
        <https://kylebarron.dev/stata_kernel/using_stata_kernel/intro/#graph-redundancy>
        """
        msg = dedent(msg)
        warn_setting = config.get('graph_redundancy_warning', 'True')
        if warn and (warn_setting.lower() == 'true'):
            self.send_response(
                self.iopub_socket, 'display_data', {
                    'data': {
                        'text/plain': msg,
                        'text/markdown': msg},
                    'metadata': {}})
        self.send_response(self.iopub_socket, 'display_data', content)

    def do_shutdown(self, restart):
        """Shutdown the Stata session

        Shutdown the kernel. You only need to handle your own clean up - the
        kernel machinery will take care of cleaning up its own things before
        stopping.
        """
        self.stata.shutdown()
        return {'restart': restart}

    def do_is_complete(self, code):
        """Decide if command has completed"""
        if self.is_complete(code):
            return {'status': 'complete'}

        return {'status': 'incomplete', 'indent': '    '}

    def do_complete(self, code, cursor_pos):
        """Provide context-aware suggestions
        """
        env, pos, chunk, rcomp = self.completions.get_env(
            code[:cursor_pos], code[cursor_pos:(cursor_pos + 2)],
            self.sc_delimit_mode, self.stata.mata_mode)

        return {
            'status': 'ok',
            'cursor_start': pos,
            'cursor_end': cursor_pos,
            'matches': self.completions.get(chunk, env, rcomp)}

    def is_complete(self, code):
        return CodeManager(
            code, self.sc_delimit_mode, self.stata.mata_mode).is_complete

    def cleanTail(self, tail, rprompt):
        """
        Search from the end of all open log files for a kernel marker
        specified by tail, typically

            . `md5 hash'

        rprompt is a regex for the prompt, typically a dot but it could
        be a `>` or a `:` (e.g. in mata). We only search up to 10 chars
        past the length of the marker for log files (unless it is a smcl
        file, in which case we search up to 100 chars back).
        """
        ltail = len(tail)
        rtail = re.escape(tail[::-1]) + ' {0,2}'
        for logfile in self.completions.suggestions['logfiles']:
            lcmp = ''
            fname, fext = os.path.splitext(logfile)
            with open(logfile, 'r+', encoding='utf-8') as fh:
                fh.seek(0, os.SEEK_END)
                pos = fh.tell() - 1
                # Note the search is inverted because we read from the end
                if fext == '.smcl':
                    maxread = pos - ltail - 100
                    rfind = rtail + '({0}|}}moc{{|[\\r\\n])'.format(rprompt)
                else:
                    rfind = rtail + rprompt
                    maxread = pos - ltail - 10
                while (pos > maxread) and (re.search(rfind, lcmp) is None):
                    lcmp += fh.read(1)
                    pos -= 1
                    fh.seek(pos, os.SEEK_SET)

                if pos > maxread:
                    fh.seek(pos + 1, os.SEEK_SET)
                    fh.truncate()

    def do_inspect(self, code, cursor_pos, detail_level=0):
        inspect_keyword = re.compile(
            r'\b(?P<keyword>\w+)\(?\s*$', flags=re.MULTILINE).search

        pre = (
            r'\b(cap(t|tu|tur|ture)?'
            r'|qui(e|et|etl|etly)?'
            r'|n(o|oi|ois|oisi|oisil|oisily)?)\b')

        inspect_mata = re.compile(
            r'^(\s*{0})*(?P<context>\w+)\b'.format(pre),
            flags=re.MULTILINE).search

        inspect_not_found = re.compile(r'help for \w+ not found').search

        ismata = False
        context = inspect_mata(code)
        if context:
            ismata = context.groupdict()['context'].strip() == 'mata'
            ismata = ismata and code.strip() != 'mata'

        found = False
        data = {}
        match = inspect_keyword(code)
        if match:
            keyword = match.groupdict()['keyword']
            if ismata:
                keyword = 'mf_' + keyword

            cm = CodeManager('help ' + keyword)
            text_to_run, md5, text_to_exclude = cm.get_text()
            rc, res = self.stata.do(
                text_to_run, md5, text_to_exclude=text_to_exclude,
                display=False)

            if inspect_not_found(res) is None:
                found = True
                data = {'text/plain': res}

        content = {
            'status': 'ok',
            # found should be true if an object was found, false otherwise
            'found': found,
            # data can be empty if nothing is found
            'data': data,
            'metadata': {}}

        return content


from node import Node
import gc

class Stack:
    def __init__(self):
        self.top = None
        self.size = 0

    def push(self, data):
        """Add an element in top of a stack"""
        node = Node(data)

        if self.top:
            node.next = self.top
            self.top = node
        else:
            self.top = node

        self.size += 1

    def length(self):
        return self.size

    def iter(self):
        """create loops with an stack"""
        probe = self.top

        while probe:
            value = probe.data
            probe = probe.next
            yield value

    def find(self, data):
        """search an element on stack"""
        probe = self.top

        while probe:
            if probe.data == data:
                return True
            else:
                probe = probe.next

        return False

    def pop(self):
        """Remove top element in a stack"""
        if self.top:
            data = self.top.data
            self.size -= 1

            if self.top.next:
                self.top = self.top.next
            else:
                self.top = None

            return data

        else:
            return "There no value on the stack"

    def peek(self):
        """Show top element in a stack"""
        if self.top:
            return self.top.data
        else:
            return "The stack is empty"

    def clear(self):
        """Remove all elemnts in a stack"""
        self.size = 0
        self.top = None
        gc.collect()


# -*- coding: utf-8 -*-
"""
Created on Fri Feb  4 13:20:14 2022

@author: Pastor
"""

# display information

def display(row1, row2, row3):
    print(row1)
    print(row2)
    print(row3)

row1 = [" ", " ", " "]
row2 = [" ", " ", " "]
row3 = [" ", " ", " "]

display(row1, row2, row3)

row2[1] = "X"

# user input by default is a string

position_index = int(input("Enter a value"))

def user_choice():

    # variables

    # initial

    choice = "WRONG"
    acceptable_range = range(0,10)
    within_range = False

    # two conditions to check
    # digit or within range == false

    while choice.isdigit() == False:

        choice = input("Please enter a number (0-10): ")

        # digit check
        if choice.isdigit() == False:
            print("Sorry that is not a digit")

        # range check
        if choice.isdigit() == True:
            if int(choice) in acceptable_range:
                within_range == False
            else:
                print()

    return int(choice)


def byte_str(n: int, group_len=8):
    if n < 0 or n > 2 ** group_len:
        raise ValueError
    return format(n, f"0{group_len}b")

def grouper(n: int, iterable: iter, filler=None) -> iter:
    iterator = iter(iterable)

    i = 0
    current = []

    while True:
        try:
            current.append(next(iterator))

            # if added last in group
            if i == n - 1:
                yield current
                current = []
                i = 0
                continue
            i += 1
        except StopIteration:
            has_unfinished_group = i != 0
            if has_unfinished_group:
                remaining = n - i
                # if relevant, fill last iteration
                if filler is not None:
                    for i in range(remaining):
                        current.append(filler)
                yield current
            break

def group_str(n, string: str, filler=None):
    for group in grouper(n, string, filler):
        yield "".join(group)

def dict_builder(*tups):
    result = {}
    v_start = 0
    for tup in tups:
        if len(tup) == 2:
            c_start, c_end = tup
        elif len(tup) == 1:
            c_start = c_end = tup
        else:
            raise ValueError(f"Invalid input: {str(tup)}")

        # update result dict
        dic = _dict_range(c_start, c_end, v_start)
        result.update(dic)

        # update start value
        len_added = len(dic.keys())
        v_start += len_added
    return result

def _dict_range(c_start, c_end, v_start):
    v_offset = v_start - ord(c_start)

    chars = (chr(i) for i in range(ord(c_start), ord(c_end) + 1))
    return {c: ord(c) + v_offset for c in chars}