import traceback

from logging import WARNING as _WARNING
from logging import getLogger
from threading import Timer as _Timer

from gi.repository import Gdk, GLib, Gtk
from logitech_receiver.settings import KIND as _SETTING_KIND
from logitech_receiver.settings import SENSITIVITY_IGNORE as _SENSITIVITY_IGNORE
from solaar.i18n import _, ngettext
from solaar.ui import ui_async as _ui_async

_log = getLogger(__name__)
del getLogger

#
#
#

def _read_async(setting, force_read, sbox, device_is_online, sensitive):

    def _do_read(s, force, sb, online, sensitive):
        v = s.read(not force)
        GLib.idle_add(_update_setting_item, sb, v, online, sensitive, priority=99)

    _ui_async(_do_read, setting, force_read, sbox, device_is_online, sensitive)

def _write_async(setting, value, sbox, sensitive=True, key=None):

    def _do_write(s, v, sb, key):
        try:
            if key is None:
                v = setting.write(v)
            else:
                v = setting.write_key_value(key, v)
                v = {key: v}
        except Exception:
            traceback.print_exc()
            v = None
        if sb:
            GLib.idle_add(_update_setting_item, sb, v, True, sensitive, priority=99)

    if sbox:
        sbox._control.set_sensitive(False)
        sbox._failed.set_visible(False)
        sbox._spinner.set_visible(True)
        sbox._spinner.start()
    _ui_async(_do_write, setting, value, sbox, key)

#
#
#

class Control():

    def __init__(**kwargs):
        pass

    def init(self, sbox, delegate):
        self.sbox = sbox
        self.delegate = delegate if delegate else self

    def changed(self, *args):
        if self.get_sensitive():
            self.delegate.update()

    def update(self):
        _write_async(self.sbox.setting, self.get_value(), self.sbox)

    def layout(self, sbox, label, change, spinner, failed):
        sbox.pack_start(label, False, False, 0)
        sbox.pack_end(change, False, False, 0)
        sbox.pack_end(self, sbox.setting.kind == _SETTING_KIND.range, sbox.setting.kind == _SETTING_KIND.range, 0)
        sbox.pack_end(spinner, False, False, 0)
        sbox.pack_end(failed, False, False, 0)
        return self

class ToggleControl(Gtk.Switch, Control):

    def __init__(self, sbox, delegate=None):
        super().__init__(halign=Gtk.Align.CENTER, valign=Gtk.Align.CENTER)
        self.init(sbox, delegate)
        self.connect('notify::active', self.changed)

    def set_value(self, value):
        self.set_state(value)

    def get_value(self):
        return self.get_state()

class SliderControl(Gtk.Scale, Control):

    def __init__(self, sbox, delegate=None):
        super().__init__(halign=Gtk.Align.FILL)
        self.init(sbox, delegate)
        self.timer = None
        self.set_range(*self.sbox.setting.range)
        self.set_round_digits(0)
        self.set_digits(0)
        self.set_increments(1, 5)
        self.connect('value-changed', self.changed)

    def get_value(self):
        return int(super().get_value())

    def changed(self, *args):
        if self.get_sensitive():
            if self.timer:
                self.timer.cancel()
            self.timer = _Timer(0.5, lambda: GLib.idle_add(self.do_change))
            self.timer.start()

    def do_change(self):
        self.timer.cancel()
        self.update()

def _create_choice_control(sbox, delegate=None, choices=None):
    if 50 > len(choices if choices else sbox.setting.choices):
        return ChoiceControlLittle(sbox, choices=choices, delegate=delegate)
    else:
        return ChoiceControlBig(sbox, choices=choices, delegate=delegate)

# GTK boxes have property lists, but the keys must be strings
class ChoiceControlLittle(Gtk.ComboBoxText, Control):

    def __init__(self, sbox, delegate=None, choices=None):
        super().__init__(halign=Gtk.Align.FILL)
        self.init(sbox, delegate)
        self.choices = choices if choices is not None else sbox.setting.choices
        for entry in self.choices:
            self.append(str(int(entry)), str(entry))
        self.connect('changed', self.changed)

    def get_value(self):
        return int(self.get_active_id()) if self.get_active_id() is not None else None

    def set_value(self, value):
        self.set_active_id(str(int(value)))

    def get_choice(self):
        id = self.get_value()
        return next((x for x in self.choices if x == id), None)

    def set_choices(self, choices):
        self.remove_all()
        for choice in choices:
            self.append(str(int(choice)), _(str(choice)))

class ChoiceControlBig(Gtk.Entry, Control):

    def __init__(self, sbox, delegate=None, choices=None):
        super().__init__(halign=Gtk.Align.FILL)
        self.init(sbox, delegate)
        self.choices = choices if choices is not None else sbox.setting.choices
        self.value = None
        self.set_width_chars(max([len(str(x)) for x in self.choices]) + 5)
        liststore = Gtk.ListStore(int, str)
        for v in self.choices:
            liststore.append((int(v), str(v)))
        completion = Gtk.EntryCompletion()
        completion.set_model(liststore)
        norm = lambda s: s.replace('_', '').replace(' ', '').lower()
        completion.set_match_func(lambda completion, key, it: norm(key) in norm(completion.get_model()[it][1]))
        completion.set_text_column(1)
        self.set_completion(completion)
        self.connect('changed', self.changed)
        self.connect('activate', self.activate)
        completion.connect('match_selected', self.select)

    def get_value(self):
        choice = self.get_choice()
        return int(choice) if choice is not None else None

    def set_value(self, value):
        self.set_text(str(next((x for x in self.choices if x == value), None)))

    def get_choice(self):
        key = self.get_text()
        return next((x for x in self.choices if x == key), None)

    def changed(self, *args):
        self.value = self.get_choice()
        icon = 'dialog-warning' if self.value is None else 'dialog-question' if self.get_sensitive() else ''
        self.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, icon)
        tooltip = _('Incomplete') if self.value is None else _('Complete - ENTER to change')
        self.set_icon_tooltip_text(Gtk.EntryIconPosition.SECONDARY, tooltip)

    def activate(self, *args):
        if self.value is not None and self.get_sensitive():
            self.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, '')
            self.delegate.update()

    def select(self, completion, model, iter):
        self.set_value(model.get(iter, 0)[0])
        if self.value and self.get_sensitive():
            self.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, '')
            self.delegate.update()

class MapChoiceControl(Gtk.HBox, Control):

    def __init__(self, sbox, delegate=None):
        super().__init__(homogeneous=False, spacing=6)
        self.init(sbox, delegate)
        self.keyBox = Gtk.ComboBoxText()
        for entry in sbox.setting.choices:
            self.keyBox.append(str(int(entry)), _(str(entry)))
        self.keyBox.set_active(0)
        key_choice = int(self.keyBox.get_active_id())
        self.value_choices = self.sbox.setting.choices[key_choice]
        self.valueBox = _create_choice_control(sbox.setting, choices=self.value_choices, delegate=self)
        self.pack_start(self.keyBox, False, False, 0)
        self.pack_end(self.valueBox, False, False, 0)
        self.keyBox.connect('changed', self.map_value_notify_key)

    def get_value(self):
        key_choice = int(self.keyBox.get_active_id())
        if key_choice is not None and self.valueBox.get_value() is not None:
            return self.valueBox.get_value()

    def set_value(self, value):
        self.valueBox.set_sensitive(self.get_sensitive())
        key = int(self.keyBox.get_active_id())
        if value.get(key) is not None:
            self.valueBox.set_value(value.get(key))
        self.valueBox.set_sensitive(True)

    def map_populate_value_box(self, key_choice):
        choices = self.sbox.setting.choices[key_choice]
        if choices != self.value_choices:
            self.value_choices = choices
            self.valueBox.remove_all()
            self.valueBox.set_choices(choices)
        current = self.sbox.setting._value.get(key_choice) if self.sbox.setting._value else None
        if current is not None:
            self.valueBox.set_value(current)

    def map_value_notify_key(self, *args):
        key_choice = int(self.keyBox.get_active_id())
        if self.keyBox.get_sensitive():
            self.map_populate_value_box(key_choice)

    def update(self):
        key_choice = int(self.keyBox.get_active_id())
        value = self.get_value()
        if value is not None and self.valueBox.get_sensitive() and self.sbox.setting._value.get(key_choice) != value:
            self.sbox.setting._value[int(key_choice)] = value
            _write_async(self.sbox.setting, value, self.sbox, key=int(key_choice))

class MultipleControl(Gtk.ListBox, Control):

    def __init__(self, sbox, change, button_label='...', delegate=None):
        super().__init__()
        self.init(sbox, delegate)
        self.set_selection_mode(Gtk.SelectionMode.NONE)
        self.set_no_show_all(True)
        self._showing = True
        self.setup(sbox.setting)  # set up the data and boxes for the sub-controls
        btn = Gtk.Button(button_label)
        btn.set_alignment(1.0, 0.5)
        btn.connect('clicked', self.toggle_display)
        self._button = btn
        hbox = Gtk.HBox(homogeneous=False, spacing=6)
        hbox.pack_end(change, False, False, 0)
        hbox.pack_end(btn, False, False, 0)
        self._header = hbox
        vbox = Gtk.VBox(homogeneous=False, spacing=6)
        vbox.pack_start(hbox, True, True, 0)
        vbox.pack_end(self, True, True, 0)
        self.vbox = vbox
        self.toggle_display()
        _disable_listbox_highlight_bg(self)

    def layout(self, sbox, label, change, spinner, failed):
        self._header.pack_start(label, False, False, 0)
        self._header.pack_end(spinner, False, False, 0)
        self._header.pack_end(failed, False, False, 0)
        sbox.pack_start(self.vbox, True, True, 0)
        sbox._button = self._button
        return True

    def toggle_display(self, *args):
        self._showing = not self._showing
        if not self._showing:
            for c in self.get_children():
                c.hide()
            self.hide()
        else:
            self.show()
            for c in self.get_children():
                c.show_all()

class MultipleToggleControl(MultipleControl):

    def setup(self, setting):
        self._label_control_pairs = []
        for k in setting._validator.get_options():
            h = Gtk.HBox(homogeneous=False, spacing=0)
            lbl_text = str(k)
            lbl_tooltip = None
            if hasattr(setting, '_labels'):
                l1, l2 = setting._labels.get(k, (None, None))
                lbl_text = l1 if l1 else lbl_text
                lbl_tooltip = l2 if l2 else lbl_tooltip
            lbl = Gtk.Label(lbl_text)
            h.set_tooltip_text(lbl_tooltip or ' ')
            control = Gtk.Switch()
            control._setting_key = int(k)
            control.connect('notify::active', self.toggle_notify)
            h.pack_start(lbl, False, False, 0)
            h.pack_end(control, False, False, 0)
            lbl.set_alignment(0.0, 0.5)
            lbl.set_margin_left(30)
            self.add(h)
            self._label_control_pairs.append((lbl, control))

    def toggle_notify(self, switch, active):
        if switch.get_sensitive():
            key = switch._setting_key
            new_state = switch.get_state()
            if self.sbox.setting._value[key] != new_state:
                self.sbox.setting._value[key] = new_state
                _write_async(self.sbox.setting, new_state, self.sbox, key=int(key))

    def set_value(self, value):
        active = 0
        total = len(self._label_control_pairs)
        to_join = []
        for lbl, elem in self._label_control_pairs:
            v = value.get(elem._setting_key, None)
            if v is not None:
                elem.set_state(v)
            if elem.get_state():
                active += 1
            to_join.append(lbl.get_text() + ': ' + str(elem.get_state()))
        b = ', '.join(to_join)
        self._button.set_label(f'{active} / {total}')
        self._button.set_tooltip_text(b)

class MultipleRangeControl(MultipleControl):

    def setup(self, setting):
        self._items = []
        for item in setting._validator.items:
            lbl_text = str(item)
            lbl_tooltip = None
            if hasattr(setting, '_labels'):
                l1, l2 = setting._labels.get(int(item), (None, None))
                lbl_text = l1 if l1 else lbl_text
                lbl_tooltip = l2 if l2 else lbl_tooltip
            item_lbl = Gtk.Label(lbl_text)
            self.add(item_lbl)
            self.set_tooltip_text(lbl_tooltip or ' ')
            item_lb = Gtk.ListBox()
            item_lb.set_selection_mode(Gtk.SelectionMode.NONE)
            item_lb._sub_items = []
            for sub_item in setting._validator.sub_items[item]:
                h = Gtk.HBox(homogeneous=False, spacing=20)
                lbl_text = str(sub_item)
                lbl_tooltip = None
                if hasattr(setting, '_labels_sub'):
                    l1, l2 = setting._labels_sub.get(str(sub_item), (None, None))
                    lbl_text = l1 if l1 else lbl_text
                    lbl_tooltip = l2 if l2 else lbl_tooltip
                sub_item_lbl = Gtk.Label(lbl_text)
                h.set_tooltip_text(lbl_tooltip or ' ')
                h.pack_start(sub_item_lbl, False, False, 0)
                sub_item_lbl.set_margin_left(30)
                sub_item_lbl.set_alignment(0.0, 0.5)
                if sub_item.widget == 'Scale':
                    control = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL, sub_item.minimum, sub_item.maximum, 1)
                    control.set_round_digits(0)
                    control.set_digits(0)
                    h.pack_end(control, True, True, 0)
                elif sub_item.widget == 'SpinButton':
                    control = Gtk.SpinButton.new_with_range(sub_item.minimum, sub_item.maximum, 1)
                    control.set_digits(0)
                    h.pack_end(control, False, False, 0)
                else:
                    raise NotImplementedError
                control.connect('value-changed', self.changed, item, sub_item)
                item_lb.add(h)
                h._setting_sub_item = sub_item
                h._label, h._control = sub_item_lbl, control
                item_lb._sub_items.append(h)
            item_lb._setting_item = item
            _disable_listbox_highlight_bg(item_lb)
            self.add(item_lb)
            self._items.append(item_lb)

    def changed(self, control, item, sub_item):
        if control.get_sensitive():
            if hasattr(control, '_timer'):
                control._timer.cancel()
            control._timer = _Timer(0.5, lambda: GLib.idle_add(self._write, control, item, sub_item))
            control._timer.start()

    def _write(self, control, item, sub_item):
        control._timer.cancel()
        delattr(control, '_timer')
        new_state = int(control.get_value())
        if self.sbox.setting._value[int(item)][str(sub_item)] != new_state:
            self.sbox.setting._value[int(item)][str(sub_item)] = new_state
            _write_async(self.sbox.setting, self.sbox.setting._value[int(item)], self.sbox, key=int(item))

    def set_value(self, value):
        b = ''
        n = 0
        for ch in self._items:
            item = ch._setting_item
            v = value.get(int(item), None)
            if v is not None:
                b += str(item) + ': ('
                to_join = []
                for c in ch._sub_items:
                    sub_item = c._setting_sub_item
                    try:
                        sub_item_value = v[str(sub_item)]
                    except KeyError:
                        sub_item_value = c._control.get_value()
                    c._control.set_value(sub_item_value)
                    n += 1
                    to_join.append(str(sub_item) + f'={sub_item_value}')
                b += ', '.join(to_join) + ') '
        lbl_text = ngettext('%d value', '%d values', n) % n
        self._button.set_label(lbl_text)
        self._button.set_tooltip_text(b)

class PackedRangeControl(MultipleRangeControl):

    def setup(self, setting):
        validator = setting._validator
        self._items = []
        for item in range(validator.count):
            h = Gtk.HBox(homogeneous=False, spacing=0)
            lbl = Gtk.Label(str(validator.keys[item]))
            control = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL, validator.min_value, validator.max_value, 1)
            control.set_round_digits(0)
            control.set_digits(0)
            control.connect('value-changed', self.changed, validator.keys[item])
            h.pack_start(lbl, False, False, 0)
            h.pack_end(control, True, True, 0)
            h._setting_item = validator.keys[item]
            h.control = control
            lbl.set_alignment(0.0, 0.5)
            lbl.set_margin_left(30)
            self.add(h)
            self._items.append(h)

    def changed(self, control, item):
        if control.get_sensitive():
            if hasattr(control, '_timer'):
                control._timer.cancel()
            control._timer = _Timer(0.5, lambda: GLib.idle_add(self._write, control, item))
            control._timer.start()

    def _write(self, control, item):
        control._timer.cancel()
        delattr(control, '_timer')
        new_state = int(control.get_value())
        if self.sbox.setting._value[int(item)] != new_state:
            self.sbox.setting._value[int(item)] = new_state
            _write_async(self.sbox.setting, self.sbox.setting._value[int(item)], self.sbox, key=int(item))

    def set_value(self, value):
        b = ''
        n = len(self._items)
        for h in self._items:
            item = h._setting_item
            v = value.get(int(item), None)
            if v is not None:
                h.control.set_value(v)
            else:
                v = self.sbox.setting._value[int(item)]
            b += str(item) + ': (' + str(v) + ') '
        lbl_text = ngettext('%d value', '%d values', n) % n
        self._button.set_label(lbl_text)
        self._button.set_tooltip_text(b)

#
#
#

_allowables_icons = {True: 'changes-allow', False: 'changes-prevent', _SENSITIVITY_IGNORE: 'dialog-error'}
_allowables_tooltips = {
    True: _('Changes allowed'),
    False: _('No changes allowed'),
    _SENSITIVITY_IGNORE: _('Ignore this setting')
}
_next_allowable = {True: False, False: _SENSITIVITY_IGNORE, _SENSITIVITY_IGNORE: True}
_icons_allowables = {v: k for k, v in _allowables_icons.items()}

# clicking on the lock icon changes from changeable to unchangeable to ignore
def _change_click(button, sbox):
    icon = button.get_children()[0]
    icon_name, _ = icon.get_icon_name()
    allowed = _icons_allowables.get(icon_name, True)
    new_allowed = _next_allowable[allowed]
    sbox._control.set_sensitive(new_allowed is True)
    _change_icon(new_allowed, icon)
    if sbox.setting._device.persister:  # remember the new setting sensitivity
        sbox.setting._device.persister.set_sensitivity(sbox.setting.name, new_allowed)
    if allowed == _SENSITIVITY_IGNORE:  # update setting if it was being ignored
        setting = next((s for s in sbox.setting._device.settings if s.name == sbox.setting.name), None)
        if setting:
            persisted = sbox.setting._device.persister.get(setting.name) if sbox.setting._device.persister else None
            if setting.persist and persisted is not None:
                _write_async(setting, persisted, sbox)
            else:
                _read_async(setting, True, sbox, bool(sbox.setting._device.online), sbox._control.get_sensitive())
    return True

def _change_icon(allowed, icon):
    if allowed in _allowables_icons:
        icon._allowed = allowed
        icon.set_from_icon_name(_allowables_icons[allowed], Gtk.IconSize.LARGE_TOOLBAR)
        icon.set_tooltip_text(_allowables_tooltips[allowed])

def _create_sbox(s, device):
    sbox = Gtk.HBox(homogeneous=False, spacing=6)
    sbox.setting = s
    sbox.kind = s.kind
    if s.description:
        sbox.set_tooltip_text(s.description)
    lbl = Gtk.Label(s.label)
    lbl.set_alignment(0.0, 0.5)
    label = Gtk.EventBox()
    label.add(lbl)
    spinner = Gtk.Spinner()
    spinner.set_tooltip_text(_('Working') + '...')
    sbox._spinner = spinner
    failed = Gtk.Image.new_from_icon_name('dialog-warning', Gtk.IconSize.SMALL_TOOLBAR)
    failed.set_tooltip_text(_('Read/write operation failed.'))
    sbox._failed = failed
    change_icon = Gtk.Image.new_from_icon_name('changes-prevent', Gtk.IconSize.LARGE_TOOLBAR)
    sbox._change_icon = change_icon
    _change_icon(False, change_icon)
    change = Gtk.Button()
    change.set_relief(Gtk.ReliefStyle.NONE)
    change.add(change_icon)
    change.set_sensitive(True)
    change.connect('clicked', _change_click, sbox)

    if s.kind == _SETTING_KIND.toggle:
        control = ToggleControl(sbox)
    elif s.kind == _SETTING_KIND.range:
        control = SliderControl(sbox)
    elif s.kind == _SETTING_KIND.choice:
        control = _create_choice_control(sbox)
    elif s.kind == _SETTING_KIND.map_choice:
        control = MapChoiceControl(sbox)
    elif s.kind == _SETTING_KIND.multiple_toggle:
        control = MultipleToggleControl(sbox, change)
    elif s.kind == _SETTING_KIND.multiple_range:
        control = MultipleRangeControl(sbox, change)
    elif s.kind == _SETTING_KIND.packed_range:
        control = PackedRangeControl(sbox, change)
    else:
        if _log.isEnabledFor(_WARNING):
            _log.warn('setting %s display not implemented', s.label)
        return None

    control.set_sensitive(False)  # the first read will enable it
    control.layout(sbox, label, change, spinner, failed)
    sbox._control = control
    sbox.show_all()
    spinner.start()  # the first read will stop it
    failed.set_visible(False)
    return sbox

def _update_setting_item(sbox, value, is_online=True, sensitive=True):
    #    sbox._spinner.set_visible(False)   # don't repack item box
    sbox._spinner.stop()
    if value is None:
        sbox._control.set_sensitive(False)
        _change_icon(False, sbox._change_icon)
        sbox._failed.set_visible(is_online)
        return
    sbox._failed.set_visible(False)
    sbox._control.set_sensitive(False)
    sbox._control.set_value(value)
    sensitive = sbox._change_icon._allowed if sensitive is None else sensitive
    sbox._control.set_sensitive(sensitive is True)
    _change_icon(sensitive, sbox._change_icon)

def _disable_listbox_highlight_bg(lb):
    colour = Gdk.RGBA()
    colour.parse('rgba(0,0,0,0)')
    for child in lb.get_children():
        child.override_background_color(Gtk.StateFlags.PRELIGHT, colour)

#
#
#

# config panel
_box = None
_items = {}

def create():
    global _box
    assert _box is None
    _box = Gtk.VBox(homogeneous=False, spacing=8)
    _box._last_device = None

    config_scroll = Gtk.ScrolledWindow()
    config_scroll.add(_box)
    config_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
    config_scroll.set_shadow_type(Gtk.ShadowType.IN)
    config_scroll.set_size_request(0, 350)  # ask for enough vertical space for about eight settings

    return config_scroll

def update(device, is_online=None):
    assert _box is not None
    assert device
    device_id = (device.receiver.path if device.receiver else device.path, device.number)
    if is_online is None:
        is_online = bool(device.online)

    # if the device changed since last update, clear the box first
    if device_id != _box._last_device:
        _box.set_visible(False)
        _box._last_device = device_id

    # hide controls belonging to other devices
    for k, sbox in _items.items():
        sbox = _items[k]
        sbox.set_visible(k[0:2] == device_id)

    for s in device.settings:
        k = (device_id[0], device_id[1], s.name)
        if k in _items:
            sbox = _items[k]
        else:
            sbox = _create_sbox(s, device)
            if sbox is None:
                continue
            _items[k] = sbox
            _box.pack_start(sbox, False, False, 0)
        sensitive = device.persister.get_sensitivity(s.name) if device.persister else True
        _read_async(s, False, sbox, is_online, sensitive)

    _box.set_visible(True)

def clean(device):
    """Remove the controls for a given device serial.
    Needed after the device has been unpaired.
    """
    assert _box is not None
    device_id = (device.receiver.path if device.receiver else device.path, device.number)
    for k in list(_items.keys()):
        if k[0:2] == device_id:
            _box.remove(_items[k])
            del _items[k]

def destroy():
    global _box
    _box = None
    _items.clear()

def change_setting(device, setting, values):
    """External interface to change a setting and have the GUI show the change"""
    assert device == setting._device
    GLib.idle_add(_change_setting, device, setting, values, priority=99)

def _change_setting(device, setting, values):
    device_path = device.receiver.path if device.receiver else device.path
    if (device_path, device.number, setting.name) in _items:
        sbox = _items[(device_path, device.number, setting.name)]
    else:
        sbox = None
    _write_async(setting, values[-1], sbox, None, key=values[0] if len(values) > 1 else None)

def record_setting(device, setting, values):
    """External interface to record a setting that has changed on the device and have the GUI show the change"""
    assert device == setting._device
    GLib.idle_add(_record_setting, device, setting, values, priority=99)

def _record_setting(device, setting, values):
    if len(values) > 1:
        setting.update_key_value(values[0], values[-1])
        value = {values[0]: values[-1]}
    else:
        setting.update(values[-1])
        value = values[-1]
    device_path = device.receiver.path if device.receiver else device.path
    if (device_path, device.number, setting.name) in _items:
        sbox = _items[(device_path, device.number, setting.name)]
        if sbox:
            _update_setting_item(sbox, value)


from fastapi import FastAPI, HTTPException, Body
import re
import json

app = FastAPI()

def reformat_string(input_string):
    questions_and_answers = re.findall(r"QS: (.+?) Answer: (.+?)(?=(?:\s*QS:|$))", input_string)
    reformatted_list = []

    for question, answer in questions_and_answers:
        prompt = {"prompt": question.strip()}
        completion = {"completion": answer.strip()}
        reformatted_list.append(json.dumps({**prompt, **completion}))

    return reformatted_list

@app.post("/reformat")
async def reformat_input_string(input_data: dict = Body(...)):
    try:
        input_string = input_data["input_string"]
        reformatted_output = reformat_string(input_string)
        return reformatted_output
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


import requests
from bs4 import BeautifulSoup

URL = "https://web.archive.org/web/20200518073855/https://www.empireonline.com/movies/features/best-movies-2/"

response = requests.get(URL)
# print(response.text)
soup = BeautifulSoup(response.text, "html.parser")

movies = soup.find_all(name="h3", class_="title")

contents = ""
for tag in movies[::-1]:
    contents += f"{tag.getText()}\n"

with open("movies.txt", mode="w", encoding="utf8") as file:
    file.write(contents)


import argparse
import logging
import schedule
import time

from libs.backups.s3_backup import raw_data_backup, reports_backup
from libs.config_engine import ConfigEngine
from libs.metrics.utils import compute_hourly_metrics, compute_daily_metrics, compute_live_metrics
from libs.reports.notifications import (send_daily_report_notification, send_daily_global_report,
                                        send_weekly_global_report)

logger = logging.getLogger(__name__)

def main(config):
    logging.basicConfig(level=logging.INFO)
    if isinstance(config, str):
        config = ConfigEngine(config)

    # Schedule configured periodic tasks
    periodic_tasks_names = [x for x in config.get_sections() if x.startswith("PeriodicTask_")]
    for p_task in periodic_tasks_names:
        if not config.get_boolean(p_task, "Enabled"):
            continue
        task_name = config.get_section_dict(p_task).get("Name")
        if task_name == "metrics":
            logger.info("Metrics enabled!")
            schedule.every().day.at("00:01").do(compute_daily_metrics, config=config)
            schedule.every().hour.at(":01").do(compute_hourly_metrics, config=config)
            live_interval = int(config.get_section_dict(p_task).get("LiveInterval", 10))
            schedule.every(live_interval).minutes.do(
                compute_live_metrics, config=config, live_interval=live_interval)
        elif task_name == "s3_backup":
            bucket_name = config.get_section_dict(p_task).get("BackupS3Bucket")
            if not bucket_name:
                logger.info("S3 Backup task doesn't have a bucket configured.")
                continue
            logger.info("Backup enabled!")
            backup_interval = int(config.get_section_dict(p_task).get("BackupInterval", 30))
            schedule.every(backup_interval).minutes.do(raw_data_backup, config=config, bucket_name=bucket_name)
            schedule.every().day.at("00:30").do(reports_backup, config=config, bucket_name=bucket_name)
        else:
            raise ValueError(f"Not supported periodic task named: {task_name}")

    # Schedule daily/weekly reports for sources and areas
    sources = config.get_video_sources()
    areas = config.get_areas()
    for src in sources:
        if src['daily_report']:
            schedule.every().day.at(src['daily_report_time']).do(
                send_daily_report_notification, config=config, entity_info=src)
    for area in areas:
        if area.daily_report:
            schedule.every().day.at(area.daily_report_time).do(
                send_daily_report_notification, config=config, entity_info=area)
    if config.get_boolean("App", "DailyGlobalReport"):
        schedule.every().day.at(config.get_section_dict("App")["GlobalReportTime"]).do(
            send_daily_global_report, config=config, sources=sources, areas=areas
        )
    if config.get_boolean("App", "WeeklyGlobalReport"):
        schedule.every(7).days.at(config.get_section_dict("App")["GlobalReportTime"]).do(
            send_weekly_global_report, config=config, sources=sources, areas=areas
        )

    while True:
        schedule.run_pending()
        time.sleep(10)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--config', required=True)
    args = parser.parse_args()
    main(args.config)


import unittest
from SurveyReportingSystem.CalculationCoordinator import CalculationCoordinator
from openpyxl import load_workbook, Workbook
import os

class ExcelWritingUtilityTestCase(unittest.TestCase):

	def setUp(self):
		wb1 = Workbook()
		ws1 = wb1.get_active_sheet()
		ws1.cell(row=1,column=1).value = "WB1Value"
		ws1.title = "WB1Sheet"
		wb1.save('wb1.xlsx')

	def test_copy_sheet_between_wb(self):
		wb2 = Workbook()
		ws2 = wb2.get_active_sheet()
		ws2.cell(row=1,column=1).value = "WB2Value"
		ws2.title = "WB2Sheet"
		wb2.save('wb2.xlsx')

		cc = CalculationCoordinator.CalculationCoordinator()
		cc.copy_sheet_to_workbook('wb1.xlsx','WB1Sheet','wb2.xlsx')

		orig_sheet = load_workbook(filename = r'wb2.xlsx').get_sheet_by_name(name = 'WB2Sheet')
		test_sheet = load_workbook(filename = r'wb2.xlsx').get_sheet_by_name(name = 'WB1Sheet')
		self.assertEqual(test_sheet.cell(row=1,column=1).value,'WB1Value')
		self.assertEqual(orig_sheet.cell(row=1,column=1).value,'WB2Value')

	def test_replace_sheet_between_wb(self):
		wb2 = Workbook()
		ws2 = wb2.get_active_sheet()
		ws2.cell(row=1,column=1).value = "WB2Value"
		ws2.title = "WB1Sheet"
		wb2.save('wb2.xlsx')

		cc = CalculationCoordinator.CalculationCoordinator()
		cc.copy_sheet_to_workbook('wb1.xlsx','WB1Sheet','wb2.xlsx')

		test_sheet = load_workbook(filename = r'wb2.xlsx').get_sheet_by_name(name = 'WB1Sheet')
		self.assertEqual(test_sheet.cell(row=1,column=1).value,'WB1Value')

	def tearDown(self):
		try:
			pass
			os.remove('wb1.xlsx')
			os.remove('wb2.xlsx')
		except:
			pass


import tensorflow as tf
import numpy as np
import random
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Conv2D,Flatten,MaxPool2D,Dropout,LeakyReLU
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import RobustScaler

# 0. seed initialization
seed = 0
random.seed(seed)
np.random.seed(seed)
tf.random.set_seed(seed)

# 1. data prepare
train_datagen=ImageDataGenerator(
    rescale=1/255,
    horizontal_flip=True,
    vertical_flip=True,
    width_shift_range=0.2,
    height_shift_range=0.1,
    rotation_range=5,
    zoom_range=1.2,
    shear_range=0.7,
    fill_mode='nearest'
)
test_datagen=ImageDataGenerator(
    rescale=1/255
)

xy_train=train_datagen.flow_from_directory('d:/study_data/_data/brain/train/'
                                  ,target_size=(200,200)
                                  ,batch_size=5
                                  ,class_mode='binary'
                                  ,color_mode='grayscale'
                                  ,shuffle=True
                                  )

xy_test=test_datagen.flow_from_directory('d:/study_data/_data/brain/test/'
                                  ,target_size=(200,200)
                                  ,batch_size=5
                                  ,class_mode='binary'
                                  ,color_mode='grayscale'
                                  ,shuffle=True
                                  )

gendata=(xy_train[i][0] for i in range(len(xy_train)))
gentarget=(xy_train[i][1] for i in range(len(xy_train)))
data=np.array(list(gendata))
data=np.reshape(data,([data.shape[0]*data.shape[1]]+list(data.shape[2:])))
target=np.array(list(gentarget))
target=np.reshape(target,([target.shape[0]*target.shape[1]]+list(target.shape[2:])))
print(data.shape)
print(target.shape)
print(target[:10])

import matplotlib as mpl
import matplotlib.pyplot as plt
plt.figure(figsize=(7,7))
for i in range(1,50):
    plt.subplot(7,7,i)
    plt.axis('off')
    plt.grid(False)
    plt.imshow(data[i],cmap='gray')
plt.show()


"""
Given a dictionary (tree), that can contains multiple nested structures.

Write a function, that takes element and finds the number of occurrences
of this element in the tree.

Tree can only contains basic structures like:
    str, list, tuple, dict, set, int, bool
"""
from typing import Any, Union

def parse_collection(
    parsed_collection: Union[list, set, tuple, str], element: Any
) -> int:
    counter = 0
    for value in parsed_collection:
        if value == element:
            counter += 1
        elif isinstance(value, dict):
            counter += find_occurrences(value, element)
        elif isinstance(value, (list, set, tuple)):
            counter += parse_collection(value, element)
        elif isinstance(element, str) and len(element) == 1 and isinstance(value, str):
            counter += value.count(element)
    return counter

def find_occurrences(tree: dict, element: Any) -> int:
    counter = 0
    for value in tree.values():
        if value == element:
            counter += 1
        elif isinstance(value, dict):
            counter += find_occurrences(value, element)
        elif isinstance(value, (list, set, tuple, str)):
            counter += parse_collection(value, element)
    return counter


import numpy as np
import matplotlib.pyplot as plt

def myhist2d(ax,x,y,Nbins=25,range=None):
    h,xed,yed=np.histogram2d(x,y,bins=Nbins,range=range)
    h=np.transpose(h)
    hmask = np.ma.masked_where( 10 > h, h)
    ax.imshow(hmask,origin='lower',extent=[xed[0],xed[-1],yed[0],yed[-1]])

x=np.random.normal(size=5000)
y=np.random.normal(size=5000)

f,axs=plt.subplots(nrows=1,ncols=2)
axs[0].hist2d(x,y,bins=25,range=[[-2,2],[-2,2]],cmin=10)
myhist2d(axs[1],x,y,range=[[-2,2],[-2,2]])

plt.show()


import math
import random
from PIL import Image, ImageColor
from random import uniform

network = []
output = [[[0],[0],[0],[0]],[[0]]]
delta_weights = [[[0],[0],[0],[0]],[[0]]]

LEARNRATE = 0.1

def init_network():
    #hidden layer, last weight = bias
    network.append([
        [0.3897357306683825, 0.9126469444394134, 0.7758730482768014], # Neuron 1, a neuron is essentially a list of weights
        [0.1735232013605318, 0.5978860651946428, 0.18040484098694443], # Neuron 2
        [0.7757205369141853, 0.5564327542525381, 0.7985897933821094], # Neuron 3
        [0.06492748093164047, 0.9280062358832749, 0.22981106076880609], # Neuron 4
    ])
    #output layer, last weight = bias
    network.append([
        [0.8497813814803977, 0.4415974940009172, 0.8888504188216229, 0.10164184412603228, 0.053793242180075196], # Neuron 1
    ])

def standard_sigmoid(arg:int, c:int = 1):
    return 1.0/(1.0 + math.exp(-c*arg))

def standard_sigmoid_derivation(arg:int):
    return arg * (1- arg)

# iterate over every weight of a neuron and multiply with the given inputs, last weight is always a bias with factor 1
def get_neuron_activation(neuron, inputs):
    sum = 0
    for i in range(len(neuron)-1):
        sum += inputs[i] * neuron[i]

    sum += 1 * neuron[-1] # bias
    return sum

# inputs bsp: [0.3, 0.5]
def get_network_output(inputs):

    for i, layer in enumerate(network):
        inputs_new = []
        for j, neuron in enumerate(layer):
            output[i][j] = standard_sigmoid(get_neuron_activation(neuron, inputs))
            inputs_new.append(output[i][j])
        inputs = inputs_new

    return output

def backward_propagation(target):

    # für jedes neuron im output layer (1x mal)
    for j in range(len(network[1])):

        error = target - output[1][j] # fehler berrechnen
        delta_weights[1][j] = error * standard_sigmoid_derivation(output[1][j]) # gewichtsveränderung berechnen und speichern

    # für jedes neuron im hidden layer (4x mal)
    for j in range(len(network[0])):
        error = 0
        for neuron in network[1]: # für jedes output neuron (1x mal)
            error += neuron[j] * delta_weights[1][0] # fehler berechnen (= Fehler am Output Neuron * Gewicht)

        delta_weights[0][j] = error * standard_sigmoid_derivation(output[0][j]) # gewichtsveränderung berechnen und speichern

def update_weights(inputs):

    # hidden layer
    for i, neuron in enumerate(network[0]): # i zum iterieren über alle delta_weights
        for j in range(len(inputs)):
            neuron[j] += LEARNRATE * delta_weights[0][i] * inputs[j]
        neuron[-1] += LEARNRATE * delta_weights[0][i] * 1 # bias

    # output layer
    for neuron in network[1]:
        for j in range(len(output[0])): # inputs für den output layer sind die outputs des hidden layer
            neuron[j] += LEARNRATE * delta_weights[1][0] * output[0][j]
        neuron[-1] += LEARNRATE * delta_weights[1][0] * 1 # bias

def is_in_unitcircle(x,y):
    x = abs(x)
    y = abs(y)
    return 1 if math.sqrt(x * x + y * y) <= 1 else 0

def printImg():
    im = Image.new('RGB', (500, 500))

    x = -1
    while (x < 1):

        y = -1
        while (y < 1):
            out = get_network_output([x,y])[1][0]

            im.putpixel((int(x * 250 + 250), int(499.98 - (y * 250 + 250))), (int(out * 255), int(out * 255), int(out * 255)))
            y += 0.002

        x += 0.002
    im.save("./KREIS.png")

def generate_testdata(n):
    testdata = []
    for i in range(n):
        x = uniform(-1.5,1.5)
        y = uniform(-1.5,1.5)
        t = is_in_unitcircle(x, y)
        testdata.append(((x, y), t))
    return testdata

def train(testdata, epochs):

    for i in range(epochs):
        sum_error = 0
        for data in testdata:
            inputs = data[0]
            target = data[1]

            get_network_output(inputs)
            sum_error += (target - output[1][0])**2
            backward_propagation(target)
            update_weights(inputs)

        print(f"Epoch: {i}; Error: {sum_error}")

def main():
    init_network()
    testdata = generate_testdata(1000)
    train(testdata, 1000)
    printImg()

main()


import argparse
import os
import re
import saassist.datacollector as datacollector
from saassist.saaserver import SAAServer
from server_config import saassist_home
from time import sleep

with open(os.path.join(os.path.dirname(__file__), 'VERSION'), 'rb') as f:
    version = f.read().decode('ascii').strip()

# header
def _print_header():
    print('=' * 80)
    print('SAAssist-server (Security APAR Assist Server) - Version {0}'.format(
        version))
    print('=' * 80)

_print_header()

# construct the command lines for server
parser = argparse.ArgumentParser(prog='saassist-server')

parser.add_argument('-c', '--create', action='store', dest='apar_download',
                    help='create CVE (Common Vulnerabilities and Exposures) '
                         'or IV (Interim Fix) repository')

parser.add_argument('-u', '--update', action='store', dest='apar_update',
                    help='update an already existent CVE/IV repository')

parser.add_argument('-l', '--list', action='store_true',
                    help='list all available CVE/IV')

parser.add_argument('-cv', '--createversion', action='store',
                    dest='os_version_download',
                    help='create the repository with all CVE/IV available for'
                         'an specific OS version')

parser.add_argument('-uv', '--updateversion', action='store',
                    dest='os_version_update',
                    help='update the repository with all CVE/IV available for'
                         'an specific OS version')

parser.add_argument('-flrt', '--flrt', action='store_true',
                    help='Update the FLRT data from FLRT IBM Website.'
                         'It will ignore the cache configuration.')

arguments = parser.parse_args()

if arguments.list:
    repo_dir = '{0}/saassist/data/repos/'.format(saassist_home)
    dir_list = os.listdir(repo_dir)
    for apar_dir in dir_list:
        if os.path.isdir(repo_dir + apar_dir):
            print(apar_dir)
    exit(0)

if arguments.flrt:
    print('[SERVER] Updating the FLRT data from FLRT IBM Website')
    flrt_download = datacollector.Collector()
    flrt_download.collect_data()
    exit(0)

# check if required arguments for -c, -u, -cv, -uv are present
apar = None
if (arguments.apar_download is None) and (arguments.apar_update is None) and\
        (arguments.os_version_download is None) and\
        (arguments.os_version_update is None):
    parser.print_help()
    apar = None
    exit()

elif (arguments.os_version_download is not None) or\
        (arguments.os_version_update is not None):

    # OS version repository
    if arguments.os_version_download is not None:
        os_version_repos = arguments.os_version_download

    if arguments.os_version_update is not None:
        os_version_repos = arguments.os_version_update

    if not re.search('[0-9][0-9[0-9][0-9]-[0-9][0-9]|[0-9].[0-9].[0-9]|ALL',
                  os_version_repos, re.IGNORECASE):

        print('[SERVER] Please use: ./saassit-server [-cv|-uv {VERSION|ALL}]\n'
              '\n'
              'Please use the correct format for version:\n'
              'AIX: NNNN-NN\n'
              'PowerVM(VIOS): N.N.N\n'
              'ALL to download available fixes from IBM.\n'
              '\n'
              'Example: ./saassist-server -cv 7100-01\n'
              '         ./saassist-server -uv 2.2.3\n'
              '         ./saassist-server -cv ALL')
        exit(1)

    # download ALL
    if os_version_repos.upper() == 'ALL':
        os_version_repos = ''

    # initializing function Collector()
    version_repos = datacollector.Collector()
    flrt_data = version_repos.flrt_data()

    # Generation apar list
    apar_list = []
    for flrt_data_row in flrt_data:
        os_versions = flrt_data_row[2]
        iv_apar = flrt_data_row[4]
        cvss = flrt_data_row[13]
        if re.search(os_version_repos, os_versions):
            if iv_apar.startswith('IV') and iv_apar in cvss:
                apar_list.append(iv_apar)
                print(iv_apar)

            if 'CVE' in cvss:
                # include the latest CVE
                apar_list.append((cvss.replace(': ',':').split()[-1]))

            else:
                apar_list.append(iv_apar)

    # removing duplicates
    apar_list = set(apar_list)
    apar_list = list(apar_list)

    if len(apar_list) is 0:
        print('[SERVER] There is not fixes available for {0}'.format(
            os_version_repos))
        exit()

    print('[SERVER] Downloading {0} fix(es) to create repos for {1} version'
          ''.format(len(apar_list), os_version_repos))

    # downloading or updating repository for OS version
    for apar_id in apar_list:
        apar_id = apar_id.split(':')[0]
        saassist_run = SAAServer(apar_id)

        if arguments.os_version_download is None:
            saassist_run.repo_creation(update=True)

        if arguments.os_version_update is None:
            saassist_run.repo_creation(update=False)

elif arguments.apar_download is None:
    apar = arguments.apar_update.upper()

else:
    apar = arguments.apar_download.upper()

# if argument os.version is not present, got to update
if apar is not None:

    # verifies if the information looks correct
    if apar.startswith('CVE') and len(apar) == 13:
        sec_id_std = True

    elif apar.startswith('IV') and len(apar) == 7:
        sec_id_std = True

    else:
        sec_id_std = False

    if sec_id_std is False:
        print('CVE or IV [{0}] number does not look correct.\n'
              'Standard is CVE-NNNN-NNNN or IVNNNNN.\n'
              'Example: CVE-2016-4948\n'
              '         IV91432\n'.format(apar))
        exit()

    # do the update action
    if arguments.apar_download is None:
        saassist_run = SAAServer(apar)
        saassist_run.repo_creation(update=True)

    if arguments.apar_update is None:
        saassist_run = SAAServer(apar)
        saassist_run.repo_creation(update=False)


# settings.py
import logging
import os
from pathlib import Path

from dotenv import load_dotenv

env_path = Path('.') / '.env'
if env_path.exists():
    load_dotenv(dotenv_path="./.env")

APP_SETTINGS = {
    "APP_NAME": "squat_machine",
    "LOG_FILE": "logs/squat_machine.json.log",
    "LOG_LEVEL": logging.getLevelName(logging.DEBUG),
}

for k, v in APP_SETTINGS.items():
    c_v = os.getenv("OV_{}".format(k))
    if (bool(c_v and c_v.strip())):
        value = os.getenv("OV_{}".format(k))
        if (APP_SETTINGS[k] == True or APP_SETTINGS[k] == False):
            if (value == 1):
                value = True
            else:
                value = False
        APP_SETTINGS[k] = value


import json
from option import  option
from DataProcessor import clip_pad_sentence,clip_pad_context
import torch
import pandas as pd
import re

class DataLoaderRec():
    def __init__(self,dataset,vocab):
        self.dataset = dataset
        self.vocab = vocab
        self.batch_size = option.batch_size
        self.history_convs = [ [] for _ in range(self.batch_size)]
        self.number_workers = option.worker_num
        self.sunset=False
        self.conv_index = 0
        self.name2id = self.get_name2id()
        self.topic_graph = self.get_topic_graph()

    def __iter__(self):
        return self

    def __next__(self):
        for i in range(len(self.history_convs)):
            if len(self.history_convs[i]) == 0:
                if not self.sunset:
                    processed_session = self.load_processed_session()
                    if processed_session is not None:
                        self.history_convs[i] = processed_session
        self.history_convs = [ conv for conv in self.history_convs if len(conv)>0 ]
        if len(self.history_convs) == 0:
            print("stop")
            raise StopIteration
        batch_convs = [ conv[0] for conv in self.history_convs ]
        self.history_convs = [ conv[1:] for conv in self.history_convs ]
        nn_inputs = []
        for idx, batch_data in enumerate(zip(*batch_convs)):
            nn_inputs.append(torch.tensor(data=batch_data, dtype=torch.long).cuda())
        return nn_inputs

    def load_processed_session(self):
        if self.conv_index >= len(self.dataset):
            self.sunset = True
            return None
        conv = self.dataset[self.conv_index]
        processed_session = self.process(conv)
        self.conv_index += 1
        return processed_session

    def process(self,conversation):
        session_segs = []
        id = int(conversation[0])
        contexts = conversation[-2]
        all_topics = conversation[-1]
        utterances = conversation[1:-2]
        uttr_len = len(utterances)
        all_topic, all_topic_len = clip_pad_sentence(all_topics, option.all_topic_num)
        all_topic = self.vocab.topic2index(all_topic)
        for i in range(2,uttr_len,2):
            response = utterances[i]
            resp = response[0]
            resp, resp_len = clip_pad_sentence(resp, max_len=option.r_max_len, sos=option.BOS_RESPONSE, eos=option.EOS_RESPONSE)
            action_R = response[2]
            if action_R == []:
                continue
            a_R, a_R_len = clip_pad_sentence(action_R, option.action_num)
            context = contexts[:i]
            context, context_len = clip_pad_context(context,option.context_max_len)
            state_R = utterances[i-2][1]
            state_R, state_R_len = clip_pad_sentence(state_R, option.state_num)
            Seeker = utterances[i-1]
            seek = Seeker[0]
            seek, seek_len = clip_pad_sentence(seek, max_len=option.r_max_len, sos=option.BOS_CONTEXT,eos=option.EOS_CONTEXT, save_prefix=False)
            state_U = Seeker[1]
            state_U, state_U_len = clip_pad_sentence(state_U,option.state_num)
            action_U = Seeker[1][-1]
            pv_action = action_U
            related_topics = self.get_related_movies(pv_action,option.movie_num)
            related_topics, related_topics_len = clip_pad_sentence(related_topics,option.movie_num)
            context_idx = self.vocab.word2index(context)
            seek_idx = self.vocab.word2index(seek)
            resp_idx = self.vocab.word2index(resp)
            state_R = self.vocab.topic2index(state_R)
            a_R = self.vocab.topic2index(a_R)
            state_U = self.vocab.topic2index(state_U)
            related_topics = self.vocab.topic2index(related_topics)
            session_segs.append([id,all_topic, all_topic_len,context_idx,context_len,
                                 state_U, state_U_len,a_R, a_R_len,seek_idx,seek_len,
                                 resp_idx,resp_len,state_R,state_R_len,related_topics,related_topics_len,1])
        session_segs[0][-1] = 0
        return session_segs

    def get_topic_graph(self):
        with open('./dataset/graph_rec.json') as f:
            topic_graph = json.load(f)
        return topic_graph

    def get_related_movies(self, action_U, relation_num):
        return self.topic_graph[action_U][0:relation_num]

    def get_name2id(self):
        name2id = {}
        movie_id = pd.read_csv('./dataset/movie_with_mentions.csv', usecols=[1, 2, 3], encoding='gbk')
        movies = movie_id.values.tolist()
        for movie in movies:
            movie[1] = re.sub('\(\d*\)', '', movie[1])
            movie[1] = re.sub('\(上\)', '', movie[1])
            movie[1] = re.sub('\(下\)', '', movie[1])
            movie[1] = re.sub('\(美版\)', '', movie[1])
            name2id[movie[1]] = str(movie[0])
        return name2id


"""first revision

Revision ID: 137f1f3f9660
Revises:
Create Date: 2017-09-27 12:55:37.219930

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '137f1f3f9660'
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('image',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('image_url', sa.String(), nullable=False),
    sa.Column('stored_on_server', sa.Boolean(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('station',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('name', sa.VARCHAR(length=30), nullable=False),
    sa.Column('stream_url', sa.VARCHAR(length=200), nullable=False),
    sa.Column('description_html', sa.VARCHAR(length=500), nullable=True),
    sa.Column('cr_tm', sa.DateTime(), nullable=False),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('station_image',
    sa.Column('station_id', sa.Integer(), nullable=True),
    sa.Column('image_id', sa.Integer(), nullable=True),
    sa.ForeignKeyConstraint(['image_id'], ['image.id'], ),
    sa.ForeignKeyConstraint(['station_id'], ['station.id'], )
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('station_image')
    op.drop_table('station')
    op.drop_table('image')
    # ### end Alembic commands ###


# -*- coding: utf-8 -*-
"""
Created on Mon May 14 19:35:36 2018

@author: mbali
"""

import numpy as np
from matplotlib import pyplot as plt
class advect:
    def __init__(self,npart=300,p=1.0,dy=1.0):
        y=np.zeros(npart)
        y[npart/3:2*npart/3]=1.0;
        self.y=y
        self.p=p
        self.dy=dy
    def get_bc_periodic(self):
        self.y[0]=self.y[-2]
        self.y[-1]=self.y[1]
    def update(self,dt=1.0):
        self.get_bc_periodic()
        delt=self.y[1:]-self.y[0:-1]
        self.y[1:-1]+=self.p*dt/self.dy*delt[1:]

if __name__=='__main__':
    stuff=advect()
    plt.ion()
    plt.plot(stuff.y)
    plt.show()
    for i in range(0,300):
        stuff.update()
        plt.clf()
        plt.plot(stuff.y)
plt.draw()


import os
import sys
import argparse
sys.path.append(os.path.join(os.path.dirname(__file__), '../'))

import numpy as np
import datetime

from specvqgan.modules.losses.vggishish.transforms import Crop
from generate_samples_batch import Diffsound

class CropImage(Crop):
    def __init__(self, *crop_args):
        super().__init__(*crop_args)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='PyTorch Training script')
    parser.add_argument('-m', '--model_path', type=str, default='../../diffsound/diffsound_audioset_audiocaps.pth')
    parser.add_argument('-a', '--audio_path', type=str)
    parser.add_argument('-s', '--save_root', type=str, default=None)
    args = parser.parse_args()

    # 0. Settings
    curr_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(curr_dir, 'caps_text.yaml')
    ckpt_vocoder = os.path.join('/'.join(curr_dir.split('/')[:-1]), 'vocoder/logs/vggsound/')

    # 1. Get the target audio and the model
    diffsound = Diffsound(config=config_path, path=args.model_path, ckpt_vocoder=ckpt_vocoder)
    spec = np.load(args.audio_path)

    # 2. Preprocess spec
    item = {}
    item['input'] = spec

    mel_num=80
    spec_crop_len=848
    transforms = CropImage([mel_num, spec_crop_len], False)

    item = transforms(item)
    image = 2 * item['input'] - 1 # why --> it also expects inputs in [-1, 1] but specs are in [0, 1]
    # image = image[None,:,:]
    spec = image.astype(np.float32)

    # 2. Recon with the VQ-VAE
    save_root = os.path.dirname(args.audio_path) if args.save_root is None else args.save_root
    save_name = os.path.basename(args.audio_path).strip('_mel.npy')
    diffsound.reconstruct_sample(spec, save_root, save_name)


import os
import tqdm
import numpy as np

import torch
from torch.autograd import Variable
from torch.utils.data import DataLoader

from ssd300.ssd import build_ssd
from helper.config import VOC_CLASSES as labels
from helper.deploy import DeployDataset, check_dir, merge_pred_true, statistics

# Init
# -------------------------
exp_root = '/home/zengyu/Lab/pytorch/standard-panel-classification'
os.chdir(exp_root)

torch.cuda.set_device(2)

# Build SSD300 in test phase
model_resume_step = 120000
num_classes = len(labels) + 1
net = build_ssd('test', 300, num_classes).eval().cuda()
net.load_weights('ssd300/weights/ssd300_0712_{}.pth'.format(model_resume_step))

def save_deployment(dataset, save_dir, batch_size=64):
    dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=False, num_workers=8)

    total_num = len(dataset)
    h, w = dataset.image_size

    deploy_results = []
    for im_batch, p_batch in tqdm.tqdm(dataloader,
                                       total=total_num // batch_size, unit=' batch({})'.format(batch_size)):
        x_batch = Variable(im_batch, volatile=True).cuda()

        detections = net(x_batch).data
        scale = torch.Tensor([w, h, w, h])  # scale each detection back up to the image

        for i, detection in enumerate(detections):
            pred = []
            for j in range(detection.size(0)):
                k = 0
                while detection[j, k, 0] >= 0.6:
                    label_name = labels[j - 1]
                    score = detection[j, k, 0]
                    pt = (detection[j, k, 1:] * scale).cpu().numpy().astype(int)
                    coords = (pt[0], pt[1]), pt[2] - pt[0] + 1, pt[3] - pt[1] + 1
                    k += 1
                    pred.append({'class': label_name, 'score': score, 'position': coords})
            deploy_results.append({'index': p_batch[i], 'prediction': pred})
    np.save(save_dir + '/{}.npy'.format('deploy_results'), deploy_results)

def main():
    for cls in ['KLAC', 'KLFE', 'KLHC']:
        save_dir = 'deployment/ssd300/{}'.format(cls)
        check_dir(save_dir)

        # dataset = DeployDataset(cls=cls)
        # save_deployment(dataset, save_dir)
        # merge_pred_true('ssd300', cls)
        statistics('ssd300', cls)
        print('*' * 30, 'Finished process {}'.format(cls), '*' * 30)

if __name__ == '__main__':
    main()


import re
import pandas as pd
import argparse

from datetime import datetime

class WordFinder(object):
    def __init__(
        self, load_dir='datasets',
        filename='republican_comments.csv'
    ):
        self.load_path = f'{load_dir}/{filename}'
        self.df = pd.read_csv(self.load_path)

    @staticmethod
    def get_search_regex(word):
        # make sure search word isn't interpreted as part
        # of the regex expression for special chars (/.*+ etc.)
        escaped_word = re.escape(word)
        # match the word only if it has whitespace before it,
        # and it has whitespace after (or it's the last word
        # in the comment). (?i) means search is case-insensitive
        pattern = re.compile(f'\\s(?i){escaped_word}(\\s|$)')
        return pattern

    @staticmethod
    def extract_sentence(comment, start_index, end_index):
        while start_index > 0:
            if comment[start_index] == '.':
                start_index += 1
                break

            start_index -= 1

        while end_index < len(comment) - 1:
            if comment[end_index] == '.':
                break

            end_index += 1

        return comment[start_index:end_index]

    @staticmethod
    def make_stamp():
        date = datetime.now()
        stamp = date.strftime('%y%m%d-%H%M')
        return stamp

    def filter_by_word(self, word):
        regex = self.get_search_regex(word)
        matches = self.df[
            self.df['comment'].str.contains(regex)
        ]
        return matches

    def show_occurrences(self, word, span=40):
        """
        show the relevant snippets of the target word
        for all comments containing said word
        """
        match_df = self.filter_by_word(word)
        regex = self.get_search_regex(word)
        num_matches = len(match_df)

        for k in range(num_matches):
            comment = match_df.iloc[k]['comment']
            match = regex.search(comment)
            start, end = match.span()
            sub_comment = comment[
                max(start-span, 0):end+span
            ]

            print(f'comment [{k}] {start, end}')
            print(sub_comment)
            # print(comment)

        print('')
        print('-' * 40)
        print(f'{num_matches} matches for [{word}]')
        print(f'dataframe = {self.load_path}')
        print(f'span = {span}')

if __name__ == '__main__':
    """
    example command:
    python3 WordFinder.py --word republican --span 100 \
    --df dem-comments-220424-1305.csv
    """
    parser = argparse.ArgumentParser(description='Enter search word.')
    parser.add_argument(
        '--word', action='store', type=str,
        const='free', default='free', nargs='?'
    )
    parser.add_argument(
        '--span', action='store', type=int,
        const=40, default=50, nargs='?'
    )
    parser.add_argument(
        '--dir', action='store', type=str,
        const='datasets', default='datasets', nargs='?'
    )
    default_file = 'republican_comments.csv'
    parser.add_argument(
        '--df', action='store', type=str,
        const=default_file, default=default_file, nargs='?'
    )

    args = parser.parse_args()
    finder = WordFinder(
        load_dir=args.dir, filename=args.df
    )

    # finder.show_occurrences('free', 50)
    finder.show_occurrences(word=args.word, span=args.span)


# -*- coding: utf-8 -*-
"""
Created on Fri Sep 14 13:57:17 2018

@author: 606C
Matplotlib demo
"""
import numpy as np
import matplotlib.pyplot as plt
from scipy.misc import imread, imresize
'''
# Compute the x and y coordinates for points on a sine curve
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
# Plot the points using matplotlib
plt.plot(x, y)
plt.show()  # You must call plt.show() to make graphics appear.

# Compute the x and y coordinates for points on sine and cosine curves
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# Plot the points using matplotlib
plt.plot(x, y_sin)
plt.plot(x, y_cos)
plt.xlabel('x axis label')
plt.ylabel('y axis label')
plt.title('Sine and Cosine')
plt.legend(['Sine', 'Cosine'])
plt.show()

# Compute the x and y coordinates for points on sine and cosine curves
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# Set up a subplot grid that has height 2 and width 1,
# and set the first such subplot as active.
plt.subplot(2, 1, 1)
# Make the first plot
plt.plot(x, y_sin)
plt.title('Sine')
# Set the second subplot as active, and make the second plot.
plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
plt.title('Cosine')
# Show the figure.
plt.show()

img = imread('cat.jpg')
img_tinted = img * [1, 0.95, 0.9]
# Show the original image
plt.subplot(1, 2, 1)
plt.imshow(img)
# Show the tinted image
plt.subplot(1, 2, 2)
# A slight gotcha with imshow is that it might give strange results
# if presented with data that is not uint8. To work around this, we
# explicitly cast the image to uint8 before displaying it.
plt.imshow(np.uint8(img_tinted))
plt.show()
'''
s = np.arange(0, 10, 0.1)

CR_err_pos = np.log(1+np.exp(-s))
CR_err_neg = np.log(1+np.exp(s))

plt.plot(s,np.log(2)+s*0)
plt.plot(s,CR_err_pos)
plt.plot(s,CR_err_neg)

plt.legend(['ln_2', 'y_and_s_equ','y_and_s_notequ'])
plt.ylabel('error')
plt.xlabel('score')
plt.title('cross-entropy error')
plt.show()


#!/usr/bin/env python

"""
This is a Cog used to display processes/ programs running on the client to a discord text channel

Commented using reStructuredText (reST)

ToDo
    create and use a database for multiple servers
"""
# Futures

# Built-in/Generic Imports
import os
import sys
import configparser
import shutil
import time
import codecs

# Libs
import discord
import psutil
from discord.ext import commands, tasks

# Own modules

__author__ = "Jack Draper"
__copyright__ = "Unofficial Copyright 2019, CyclopsBot"
__credits__ = ["Jack Draper"]
__license__ = "Developer"
__version__ = "0.0.4"
__maintainer__ = "Jack Draper"
__email__ = "thejaydwee@gmail.com"
__status__ = "Development"
# "Prototype", "Development", or "Production"

# Constants
CONFIG_PATH = "./configs/config.ini"
DEFAULT_EMBED = discord.Embed(
            title=":desktop: Program Status",
            colour=discord.Colour.blue()
        )

# Checks for config file
if not os.path.exists("./configs/config.ini"):
    print("No config file can be found in ./configs/.")
    sys.exit("No config found.")
# Runs config file
config = configparser.ConfigParser()
try:
    # config.read(os.path.abspath("./configs/config.ini"))
    config.read_file(codecs.open(CONFIG_PATH, "r", "utf-8-sig"))
except FileNotFoundError:
    try:
        # shutil.copyfile("./configs/default_config.ini", "./configs/config.ini")
        print("You need to set up the config file correctly.")
    except shutil.Error:
        print("Something is wrong with the default config file or the config folder.")
        time.sleep(4)
    sys.exit()

# Config Constants
ADMIN_ROLE = config["Credentials"]["admin_role"]
TEXT_CHANNEL = int(config["ProcessDisplay"]["text_channel_id"])
PROCESSES = eval(config["ProcessDisplay"]["processes"])

class ProcessDisplay(commands.Cog):
    """
    The Cog for Process Display
    """

    def __init__(self, client):
        """
        :param client: the bot client parsed in from the main program
        """
        self.started = False
        self.client = client
        self.inline = False

    # Events
    @commands.Cog.listener()
    async def on_ready(self):
        """
        Ran when bot is starting up and ready
        Deletes messages from the bot in the TEXTCHANNEL
        starts up find_processes method
        :return:
        """

        if not self.started:
            channel = self.client.get_channel(TEXT_CHANNEL)

            await self.delete_bot_msg(channel)
            msg = await channel.send(embed=DEFAULT_EMBED)
            self.find_processes.start(msg)
            started = True
        print("ProcessDisplay Running")

    # Commands
    @commands.command()
    @commands.has_permissions(administrator=True)
    async def toggle_inline(self,ctx):
        """
        Toggles inline for process controls

        :param ctx: The command Context
        :return:
        """
        self.inline = not self.inline

    @commands.command()
    @commands.has_permissions(administrator=True)
    async def move_process(self, direction, process_name):
        """
        need to make
        :param direction:
        :param process_name:
        :return:
        """
        for i in range(len(PROCESSES)):
            if PROCESSES[i] == process_name:
                if direction.lower() == "up":
                    pass

    @commands.command()
    @commands.has_permissions(administrator=True)
    async def add_process(self, ctx, process, name):
        """
        Adds a process to the process display.
        Must be different from ones currently displayed.

        :param ctx: Context of the command
        :param process: The process (e.g. 'cmd.exe') to be added
        :param name: The name to be displayed for the process (e.g. 'Command Prompt')
        :return:
        """
        name = self.fix_emoji_escapes(name)
        if process in PROCESSES.keys():
            await ctx.send(f"The process {process} is already being displayed")
        elif name in PROCESSES.values():
            await ctx.send(f"The process name {name} is already being displayed")

        else:
            PROCESSES[process] = name
            self.update_processes_config()
            await ctx.send(f"The process {name} has been added")

    @commands.command()
    @commands.has_permissions(administrator=True)
    async def remove_process(self, ctx, *name):
        """
        Removes a process from the process display

        :param ctx: Context of the command
        :param name: Name displayed for the process (e.g. Command Prompt)
        :return:
        """
        print(name)
        name = self.fix_emoji_escapes(" ".join(name))
        complete = False
        for process in PROCESSES.keys():
            if PROCESSES.get(process) == name:
                PROCESSES.pop(process)
                self.update_processes_config()
                await ctx.send(f"The process {name} has been removed")
                complete = True
                break
        if not complete:
            await ctx.send(f"The process {name} doesn't exist")

    @commands.command()
    @commands.has_permissions(administrator=True)
    async def edit_process(self, ctx, old_name, new_name):
        """
        Edits the name of a process
        :param ctx: The context of the command
        :param old_name: The old name of the process (to be changed)
        :param new_name: The new name of the process (changed to)
        :return:
        """
        old_name = self.fix_emoji_escapes(old_name)
        new_name = self.fix_emoji_escapes(new_name)
        if old_name in PROCESSES.values():
            for process in PROCESSES:
                if PROCESSES.get(process) == old_name:
                    PROCESSES.update({process: new_name})
                    self.update_processes_config()

        else:
            await ctx.send(f"Process name {old_name} doesn't exist")

    @tasks.loop(seconds=1)
    async def find_processes(self, msg):
        """
        The processes with statuses are attached to the msg given

        :param msg: The message to be edited with the processes
        :return:
        """
        running_processes = []
        new_embed = DEFAULT_EMBED.copy()

        for proc in psutil.process_iter():
            if proc.name() in PROCESSES.keys():
                running_processes.append(proc.name())
            elif proc.name() in ["java.exe", "javaw.exe"] and proc.cwd() in PROCESSES.keys():
                running_processes.append(proc.cwd())

        for process in PROCESSES:
            try:
                if process in running_processes:
                    new_embed.add_field(name=PROCESSES.get(process),
                                        value="Online <:GreenTick:592083498534174721>", inline=self.inline)
                else:
                    new_embed.add_field(name=PROCESSES.get(process),
                                        value="Offline <:RedCross:592082557961633877>", inline=self.inline)
            except PermissionError:
                new_embed.add_field(name=PROCESSES.get(process),
                                    value="Admin Required <:OrangeUnknown:592082676891123722>", inline=self.inline)
        await msg.edit(content="", embed=new_embed)

    def is_me(self, m):
        """
        Checks if a messages author is the bot
        :param m: tbh idk, maybe message?
        :return:
        """
        return m.author == self.client.user

    async def delete_bot_msg(self, channel):
        """
        Deletes up to the last 100 messages sent by the bot in the given channel
        :param channel: The channel that will have the messages deleted
        :return: the message that says how many messages were deleted
        """
        await channel.purge(limit=100, check=self.is_me)

    @staticmethod
    def update_processes_config():
        """
        Updates the processes line in the config with the current PROCESSES
        :return:
        """

        config.set("ProcessDisplay", "processes", str(PROCESSES))
        with open(CONFIG_PATH, 'w', encoding='utf-8') as configfile:
            config.write(configfile)

    @staticmethod
    def fix_emoji_escapes(text):
        """
        Fixes emoji escapes to add the < back on
        :param text: The text that needs to be checked for an escape
        :return: the fixed text
        """
        new_text = text.split(":")
        for i in range(2, len(new_text)):
            if ">" in new_text[i]:
                new_text[i-2] += "<"
        return ":".join(new_text)

def setup(client):
    """
    Ran on setup of the Cog
    :param client: The bot client
    :return:
    """
    client.add_cog(ProcessDisplay(client))


from bokeh.plotting import *

import numpy as np
import time
import datetime as dt
import os
import random

# Define a function that will return an HTML snippet.
def build_plot():
    figure()
    hold()

    #Time initizilation
    To = int(time.time())
    From = To - 86400

    #Go to the sensors directory
    os.chdir('sensors/')

    #Loop throuch all the sensors
    for i in os.listdir(os.getcwd()):
        #hold()
        #some inits
        dates = []
        values = []
        data_dict = {}
        #Change directory to the current sensor
        os.chdir(i)
        #Make a list of the files in the given time seconds back in time
        file_list = [l for l in os.listdir(os.getcwd())]
        #Loop through those files
        for j in file_list:
            #Open the files
            with open(j, 'r') as f:
                #loop through the data
                for k in f:
                    #Split the time and data values
                    split_list = k.split('|')
                    #If the data is within the given time frame,
                    #add it to the dict, the first field is timethe second data
                    if To > int(split_list[0]) > From:
                        data_dict[split_list[0]] = split_list[1]

        #Loop through the created dict
        for key in sorted(data_dict.keys()):
            #Append the lists, List concetation???????????????
            dates.append(dt.datetime.fromtimestamp(int(key)))
            values.append(data_dict[key])
        #Some more configuration of the plot
        #ax.plot_date(dates, values, '-', label='aaa')
        #Change the directory for next sensor
        os.chdir('..')
        line(dates, values, legend=i, x_axis_type='datetime')
    os.chdir('..')
    # Set the output for our plot.

    output_file('plot.html', title='Plot')

    figure()

    # Create some data for our plot.

    x_data = np.arange(1, 101)
    y_data = np.random.randint(0, 101, 100)

    # Create a line plot from our data.

    line(x_data, y_data)

    # Create an HTML snippet of our plot.

    #snippet = curplot().create_html_snippet(embed_base_url='../static/js/', embed_save_loc='./static/js')

    show()

    # Return the snippet we want to place in our page.

    #return snippet

if __name__ == '__main__':
    build_plot()


import gym
from gym import error, spaces, utils, logger
from gym.utils import seeding

import cityflow
import numpy as np

import json
import random

class CityFlow1x1(gym.Env):
    metadata = {'render.modes':['human']}

    def __init__(self, cfgs, steps_per_episode=100):
        # self.cfgs = glob.glob('data/rl/cfg_*')
        self.cfgs = cfgs
        with open(cfgs[0]) as f:
            cfg = json.load(f)

        self.cf_engine = cityflow.Engine(cfgs[0], thread_num=1)
        # self.cf_engine.set_save_replay(False)

        with open(cfg['dir'] + cfg['flowFile']) as f:
            flow_cfg = json.load(f)

        self.all_lade_ids = [lane_id for lane_id in
                             self.cf_engine.get_lane_vehicles()]

        start_road_ids = []
        for v in flow_cfg:
            start_road_ids.append(v['route'][0])

        self.start_lane_ids = []
        for lane_id in self.all_lade_ids:
            for road_id in start_road_ids:
                if lane_id.startswith(road_id):
                    self.start_lane_ids.append(lane_id)
                    break

        self.step_interval = float(cfg['interval'])

        # actual phases
        # self.phase_durs = np.array([10] * 9, dtype=np.int64)
        # self.phases = np.arange(9)

        # demo phases
        self.phase_durs = [30, 30]
        self.phases = [1, 2]

        # fuck it, let's hardcode the intersection id and number of TL states
        self.inter_id = 'intersection_1_1'
        # self.action_space = spaces.Discrete(9) # 9 TL phases
        self.action_space = spaces.Discrete(len(self.phases))

        n_start_lanes = len(self.start_lane_ids)
        max_vehicles_per_lane = 100
        n_buckets = int(np.log2(1 + max_vehicles_per_lane))

        self.observation_space = spaces.MultiDiscrete([n_buckets] * n_start_lanes)

        self.steps_per_episode = steps_per_episode
        self.current_step = 0
        self.is_done = False
        self.reward_range = (float('-inf'), 0)

        self.waiting_dict = {}
        self.last_tick_time = 0

    def step(self, action):
        assert self.action_space.contains(action), f'invalid action specified: {action}'

        cum_reward = 0
        for _ in range(self.phase_durs[action]):
            self.cf_engine.set_tl_phase(self.inter_id, self.phases[action])
            self.cf_engine.next_step()
            state, reward = self._get_state_reward()
            cum_reward += reward

        self.current_step += 1

        if self.is_done:
            logger.warn("You are calling 'step()' even though this environment "
                        "has already returned done = True. You should always call "
                        "'reset()' once you receive 'done = True' -- any further "
                        "steps are undefined behavior.")
            cum_reward = 0

        if self.current_step == self.steps_per_episode:
            self.is_done = True

        return state, cum_reward, self.is_done, {}

    def seed(self, n):
        self.cf_engine.set_random_seed(n)

    def reset(self, seed=None):
        if seed is not None:
            self.seed(seed)
            random.seed(seed)

        self.cf_engine = cityflow.Engine(random.choice(self.cfgs),
                                         thread_num=1)
        # self.cf_engine.set_save_replay(False)

        self.cf_engine.reset()
        self.is_done = False
        self.current_step = 0
        self.last_tick_time = 0
        self.waiting_dict.clear()

        state, _ = self._get_state_reward()

        return state

    def set_save_replay(self, save_replay):
        self.cf_engine.set_save_replay(save_replay)

    def set_replay_path(self, path):
        self.cf_engine.set_replay_file(path)

    def _get_state_reward(self):
        waiting_per_lane = self.cf_engine.get_lane_waiting_vehicle_count()

        n_start_lanes = len(self.start_lane_ids)
        counts = np.zeros(n_start_lanes, dtype=np.int64)
        for i in range(n_start_lanes):
            counts[i] = waiting_per_lane[self.start_lane_ids[i]]

        state = np.log2(1 + counts).astype(np.int64)

        cur_time = self.cf_engine.get_current_time()
        elapsed = cur_time - self.last_tick_time
        self.last_tick_time = cur_time
        impatience = 0.0
        alpha = 10**(1.0/100)
        for v_id, speed in self.cf_engine.get_vehicle_speed().items():
            if abs(speed) < 0.1:
                t = self.waiting_dict.get(v_id, 1) * elapsed * alpha
                self.waiting_dict[v_id] = t
                impatience += t

        reward = -counts.sum()# - min(impatience, 1e3)

        return state, reward


import logging
import re
import codecs
from cgi                      import escape
from exe.webui.blockfactory   import g_blockFactory
from exe.engine.error         import Error
from exe.engine.path          import Path, TempDirPath
from exe.export.pages         import uniquifyNames
from exe.export.ipodpage      import IpodPage

log = logging.getLogger(__name__)

# ===========================================================================
class IpodExport(object):
    """
    IpodExport will export a package as iPod folder tree
    """
    def __init__(self, config, filename):
        """
        'outputDir' is the directory that will be [over]written
        """
        self.config       = config
        self.filename     = Path(filename)
        self.pages        = []

    def export(self, package):
        """
        Export as iPod notes
        """
        outputDir = self.filename
        if not outputDir.exists():
            outputDir.mkdir()
        fileDir = outputDir/"{files}"
        fileDir.mkdir()

        self.pages = [ IpodPage("index", 1, package.root) ]
        self.generatePages(package.root, 1)
        uniquifyNames(self.pages)

        prevPage = None
        thisPage = self.pages[0]

        for nextPage in self.pages[1:]:
            thisPage.save(fileDir, prevPage, nextPage, self.pages)
            prevPage = thisPage
            thisPage = nextPage

        thisPage.save(fileDir, prevPage, None, self.pages)
        self.writeNavigation(outputDir, package)

    def generatePages(self, node, depth):
        """
        Recursively generate pages and store in pages member variable
        for retrieving later
        """
        for child in node.children:
            pageName = child.titleShort.lower().replace(" ", "_")
            pageName = re.sub(r"\W", "", pageName)
            if not pageName:
                pageName = "__"

            self.pages.append(IpodPage(pageName, depth, child))
            self.generatePages(child, depth + 1)

    def writeNavigation(self, outputDir, package):
        html = "<title>%s</title>\n" % escape(package.title)
        for page in self.pages:
            html += '%s%s\n' % (
                    page.name,
                    '  ' * page.depth,
                    page.node.titleShort)

        outfile = codecs.open(outputDir / "index.linx", mode='w',
                encoding='utf-8')
        outfile.write(html)
        outfile.close()


import os
from tablib import Dataset
import pandas
import pygal
from flask import Flask, flash, request, redirect, render_template
from werkzeug.utils import secure_filename

# uploads folder should be exesit
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'uploads')
ALLOWED_EXTENSIONS = {'CSV','csv'}

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.secret_key = f'_5#y2L"F4Q8z\n\xec]/'

file_name = ""
dataset = Dataset()

@app.route('/')
def hello():
    return render_template('home.html')

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload', methods=['POST', 'GET'])
def upload():
    global file_name
    if request.method == 'POST':
        # check if the post request has the file part
        if 'inputFile' not in request.files:
            flash('No file part')
            # print("Not inputFile")
            return redirect(request.url)
        file = request.files['inputFile']
        # if user does not select file, browser also
        # submit an empty part without filename
        if file.filename == '':
            # print("Not selected")
            flash('No selected file')
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)

            file.save(os.path.join(app.config['UPLOAD_FOLDER'], str(filename)))
            file_name = os.path.join(
                app.config['UPLOAD_FOLDER'], str(filename))

            return redirect("show")

        else:
            flash("That file don't allow to use ")
    return render_template("home.html")

@app.route("/show")
def show():
    global header
    global data
    global option
    if file_name == "":
        return redirect("/")
    else:
        with open(file_name, "r") as line:
            dataset.csv = line.read()
        data = dataset.html
        option = ["mean","sum","max","min","count","median","std","var"]
        header = open(file_name).readline().rstrip()
        print(header)
        if "," in header:
        	header = open(file_name).readline().rstrip().split(",")
        elif " " in header:
        	header = open(file_name).readline().rstrip().split(" ")
        elif "." in header:
        	header = open(file_name).readline().rstrip().split(".")
        else:
        	flash("that header of file not support split ")
        	return redirect("/")

        return render_template("show.html", lines=data, option=option, header=header)

@app.route("/analyze")
def analyze():
    name = request.args.get("myselect")
    option_var = request.args.get("myoption")

    if name not in header:
        flash("please select the header and option")
        return redirect("/")
    elif option_var not in option:
        flash("option not found ")
        return redirect("/")

    df = pandas.read_csv(file_name)
    try:
        if option_var == "mean":
            set_data = df[name].mean()
        elif option_var == "sum":
            set_data = df[name].sum()
        elif option_var == "max":
            set_data = df[name].max()
        elif option_var == "count":
            set_data = df[name].count()
        elif option_var == "std":
            set_data = df[name].std()
        elif option_var == "var":
            set_data = df[name].var()
        elif option_var == "min":
            set_data = df[name].min()
    except:
        flash("pleas make sure use the option with the valid header you can't use some option with string value !")
        return redirect("/")

    imported_data = Dataset().load(open(file_name).read())
    data = imported_data[name]
    new_list = []
    for d in data:
        try:
            if d.isdigit():
                new_list.append(int(d))
            elif type(d) == str:
                new_list.append(float(d))
        except:
            flash("this option only for Number")
            return redirect("/")

    graph = pygal.Line()
    graph.title = "Full customization option For " + str(name)
    graph.x_labels = []
    graph.add(name, new_list)
    graph_data = graph.render_data_uri()

    return render_template("analyze.html", set_data=set_data, option_var=option_var, name=name, graph_data=graph_data)

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


import firebase_admin
from firebase_admin import firestore
from firebase_admin import credentials

cred = credentials.Certificate('aibigdata-ntut-107598064-firebase.json')
firebase_admin.initialize_app(cred)
dataBase = firestore.client().collection('test')
dataBase_sites = dataBase.document('myfirestore').collection('sites')
sites = []
for document in dataBase_sites.stream():
    site = document.to_dict()
    sites.append(site['id'])
print(sites)


import discord
import json, urllib.request, requests
from ratelimit import limits, sleep_and_retry

async def ranked_search(account_name,account_id,summoner_id,key,message):
    player_ranking_URL = "https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/"+ summoner_id +"?api_key=" + key
    player_ranking_info = requests.get(player_ranking_URL).json()
    for queue_type in player_ranking_info:
        if queue_type['queueType'] == 'RANKED_SOLO_5x5':
            await message.channel.send(account_name + f'\'s current rank is: {queue_type["tier"].capitalize()} {queue_type["rank"]}')
            break
    else:
        await message.channel.send("Hmm, " + account_name + " isn\'t ranked in solo/duo right now. There might be some results from earlier seasons though.")
    await message.channel.send("Loading results...")
    match_history_url = 'https://na1.api.riotgames.com/lol/match/v4/matchlists/by-account/' + account_id + '?queue=420&endIndex=80&api_key=' + key
    match_history_data = requests.get(match_history_url).json()
    match_id_list = []
    for match in match_history_data['matches']:
        match_id_list.append(match['gameId'])
    player_list = {}
    for match in match_id_list:
        match_id = match
        match_url = 'https://na1.api.riotgames.com/lol/match/v4/matches/' + str(match_id) + '?api_key=' + key
        match_details = requests.get(match_url).json()
        team_side = []
        try:
            match_details['participantIdentities']
        except:
            await message.channel.send("Unable to get the recent player's matches. Most likely the API call limit was reached, so wait at least two minutes and try again.")
            return
        for player in match_details['participantIdentities']:
            if player['player']['accountId'] == account_id:
                if player['participantId'] in [1,2,3,4,5]:
                    team_side = [0,1,2,3,4]
                else:
                    team_side = [5,6,7,8,9]
        for participantId in team_side:
            if match_details['participantIdentities'][participantId]['player']['accountId'] != account_id:
                player_name = match_details['participantIdentities'][participantId]['player']['summonerName']
                player_list[player_name] = player_list.get(player_name,0) + 1
    edited_player_list = player_list.copy()
    for player_key in player_list:
        if player_list[player_key] in [1,2]:
            del edited_player_list[player_key]
    ordered_player_list = sorted(edited_player_list.items(), key=lambda x: x[1], reverse=True)
    if len(ordered_player_list) == 0:
        await message.channel.send("You haven't played with anyone recently...damn")
        return
    total_duoed_games = 0
    for x in ordered_player_list:
        await message.channel.send(f'Summoner Name: {x[0]} | Total Games Duoed: {x[1]} | Percent Duoed With This Person: {round(((x[1]/len(match_id_list)) * 100),2)}%')
        total_duoed_games += x[1]
    if 100 * total_duoed_games/len(match_id_list) > 100:
        await message.channel.send(f'Overall, {account_name} has duoed 100% of his/her games.')
        return
    await message.channel.send(f'Overall, {account_name} has duoed {round(100 * total_duoed_games/len(match_id_list), 2)}% of his/her games.')
    await message.channel.send('Disclaimer: a person only shows up if they duoed more than 2 games. There\'s also a chance (especially in higher elos) that some people who show up are just random players \
who happened to be on the same team multiple times.')


from flask import flash
from models import User

def handle_signup_errors(username, email, id):
    """Handles errors for signup or updating profile"""

    existing_username = User.query.filter_by(username=username).one_or_none()
    existing_email = User.query.filter_by(email=email).one_or_none()

    if existing_username and existing_username.id != id:
        flash("Username already taken, try a different username", 'danger')
        return True
    if existing_email and existing_email.id != id:
        flash("Email already in use", "danger")
        return True

    else:
        return False


import sys
import os
beauvoir_path = os.path.dirname(os.path.realpath(__file__)) + '/'
sys.path.append(beauvoir_path)
sys.path.append('/usr/local/lib/python3.5/dist-packages/')
from utils.image_detector_generator import ImageDetectorGenerator

obj_model_directory = '../data/ShapeNetCore.v2/'
save_path = '../data/detection_data/'
background_path = '../data/backgrounds/'
class_names = ['airplane', 'bench', 'bottle', 'bus', 'camera', 'can', 'car',
               'cellular_telephone', 'chair', 'computer_keyboard', 'display',
               'earphone', 'faucet', 'guitar', 'knife', 'laptop', 'motorcycle',
               'mug', 'pillow', 'pistol', 'rifle', 'rocket', 'skateboard',
               'table']

num_images = 500
resolution = (300, 300)
background = 'crop'
max_num_lamps = 3
translation_range = [-1, 1]
max_num_objects_in_scene = 5

image_generator = ImageDetectorGenerator(
                        obj_model_directory, save_path,
                        class_names, num_images,
                        resolution, background=background,
                        background_images_directory=background_path,
                        max_num_lamps=max_num_lamps,
                        translation_range=translation_range,
                        max_num_objects_in_scene=max_num_objects_in_scene)

image_generator.render()