"""
REM Layout classes and functions.
"""
import PySimpleGUI as sg

import REM.constants as mod_const
import REM.data_manipulation as mod_dm
from REM.client import logger, settings, user

# Modifier functions
def set_size(window, element_key, size):
    """
    Set new size for container-like elements.
    """
    options = {'width': size[0], 'height': size[1]}

    element = window[element_key]
    try:
        scrollable = element.Scrollable
    except AttributeError:
        scrollable = False

    if scrollable:
        element.Widget.canvas.configure(**options)
        element.contents_changed()
    else:
        element.Widget.pack_propagate(0)
        element.set_size(size)

    window.refresh()

# GUI Element Functions
def generate_layout(etype, attributes):
    """
    Generate a layout for different element types.
    """
    func_mapper = {'input': input_layout, 'multiline': multiline_layout, 'dropdown': combo_layout,
                   'checkbox': checkbox_layout, 'text': text_layout}
    try:
        layout_func = func_mapper[etype]
    except KeyError:
        logger.warning('unknown element type "{ETYPE}" provided'.format(ETYPE=etype))
        layout_func = func_mapper['text']

    layout = layout_func(attributes)

    return layout

def text_layout(attributes):
    # Standard element parameters
    font = attributes.get('Font', mod_const.LARGE_FONT)
    size = attributes.get('Size', None)
    bw = attributes.get('BW', 0)
    pad = attributes.get('Pad', None)
    bg_col = attributes.get('BackgroundColor', mod_const.DEFAULT_BG_COLOR)
    text_col = attributes.get('TextColor', mod_const.DISABLED_TEXT_COLOR)
    tooltip = attributes.get('Tooltip', None)
    events = not attributes.get('Disabled', False)

    # Element layout
    elem_key = attributes['Key']
    display_value = attributes.get('DisplayValue', None)
    layout = [sg.Text(display_value, key=elem_key, enable_events=events, size=size, pad=pad, background_color=bg_col,
                      text_color=text_col, font=font, border_width=bw, relief='sunken', tooltip=tooltip)]

    return layout

def input_layout(attributes):
    # Standard element parameters
    font = attributes.get('Font', mod_const.LARGE_FONT)
    size = attributes.get('Size', None)
    pad = attributes.get('Pad', None)
    bw = attributes.get('BW', 1)
    bg_col = attributes.get('BackgroundColor', mod_const.DEFAULT_BG_COLOR)
    text_col = attributes.get('TextColor', mod_const.DEFAULT_TEXT_COLOR)

    disabled = attributes.get('Disabled', False)
    tooltip = attributes.get('Tooltip', None)

    # Element layout
    elem_key = attributes['Key']
    display_value = attributes.get('DisplayValue', '')
    layout = [sg.Input(display_value, key=elem_key, enable_events=True, disabled=disabled, size=size, pad=pad,
                       font=font, background_color=bg_col, text_color=text_col, border_width=bw,
                       disabled_readonly_background_color=bg_col, disabled_readonly_text_color=text_col,
                       tooltip=tooltip, metadata={'disabled': disabled})]

    return layout

def combo_layout(attributes):
    # Standard element parameters
    font = attributes.get('Font', mod_const.LARGE_FONT)
    size = attributes.get('Size', None)
    pad = attributes.get('Pad', None)
    bg_col = attributes.get('BackgroundColor', mod_const.DEFAULT_BG_COLOR)
    text_col = attributes.get('TextColor', mod_const.DEFAULT_TEXT_COLOR)

    disabled = attributes.get('Disabled', False)
    tooltip = attributes.get('Tooltip', None)

    # Combobox parameters
    values = attributes.get('ComboValues', [])

    # Element layout
    elem_key = attributes['Key']
    display_value = attributes.get('DisplayValue', '')
    layout = [sg.Combo(values, default_value=display_value, key=elem_key, enable_events=True, size=size, pad=pad,
                       font=font, text_color=text_col, background_color=bg_col,
                       button_arrow_color=mod_const.BORDER_COLOR, button_background_color=bg_col,
                       expand_x=True, expand_y=True,
                       disabled=disabled, tooltip=tooltip, metadata={'disabled': disabled})]

    return layout

def multiline_layout(attributes):
    # Standard element parameters
    font = attributes.get('Font', mod_const.LARGE_FONT)
    size = attributes.get('Size', None)
    pad = attributes.get('Pad', None)
    bw = attributes.get('BW', 1)
    bg_col = attributes.get('BackgroundColor', mod_const.DEFAULT_BG_COLOR)
    def_text_col = attributes.get('TextColor', mod_const.DEFAULT_TEXT_COLOR)
    disabled_text_col = mod_const.DISABLED_TEXT_COLOR

    disabled = attributes.get('Disabled', False)
    tooltip = attributes.get('Tooltip', None)

    if disabled:
        text_col = disabled_text_col
    else:
        text_col = def_text_col

    # Multiline parameters
    height = attributes.get('NRow', 1)
    width = size[0]

    # Element layout
    elem_key = attributes['Key']
    display_value = attributes.get('DisplayValue', '')
    layout = [sg.Multiline(display_value, key=elem_key, size=(width, height), pad=pad, font=font, disabled=disabled,
                           background_color=bg_col, text_color=text_col, border_width=bw,
                           tooltip=tooltip, metadata={'disabled': disabled})]

    return layout

def checkbox_layout(attributes):
    # Standard element parameters
    font = attributes.get('Font', mod_const.LARGE_FONT)
    size = attributes.get('Size', None)
    pad = attributes.get('Pad', None)
    bg_col = attributes.get('BackgroundColor', mod_const.DEFAULT_BG_COLOR)
    text_col = attributes.get('TextColor', mod_const.DEFAULT_TEXT_COLOR)

    disabled = attributes.get('Disabled', False)
    tooltip = attributes.get('Tooltip', None)

    # Checkbox settings
    box_col = bg_col if not disabled else mod_const.DISABLED_BG_COLOR

    width, height = size
    elem_w = 0
    elem_h = height

    # Parameter settings
    elem_key = attributes['Key']
    display_value = attributes.get('DisplayValue', False)
    layout = [sg.Checkbox('', default=display_value, key=elem_key, enable_events=True, disabled=disabled,
                          size=(elem_w, elem_h), pad=pad, font=font, background_color=bg_col, text_color=text_col,
                          checkbox_color=box_col, tooltip=tooltip, metadata={'disabled': disabled})]

    return layout

def button_layout(bttn_key, icon: str = None, **kwargs):
    """
    Program button layout.
    """
    # Button constants
    text_color = mod_const.DEFAULT_TEXT_COLOR
    disabled_text_color = mod_const.DISABLED_TEXT_COLOR
    bg_color = mod_const.BORDER_COLOR
    disabled_bg_color = mod_const.BORDER_COLOR
    highlight_color = mod_const.BUTTON_HOVER_COLOR
    size = mod_const.BTTN_SIZE

    bttn_icon = icon if icon is not None else mod_const.BLANK_ICON
    layout = sg.Button('', key=bttn_key, image_data=bttn_icon, image_size=size, button_color=(text_color, bg_color),
                       disabled_button_color=(disabled_text_color, disabled_bg_color),
                       mouseover_colors=(text_color, highlight_color), border_width=1, use_ttk_buttons=False, **kwargs)

    return layout

def create_table_layout(data, header, keyname, events: bool = False, bind: bool = False, tooltip: str = None,
                        nrow: int = None, height: int = 800, width: int = 1200, font: tuple = None, pad: tuple = None,
                        table_name: str = ''):
    """
    Create table elements that have consistency in layout.
    """
    # Element settings
    text_col = mod_const.DEFAULT_TEXT_COLOR
    alt_col = mod_const.TBL_ALT_COLOR
    bg_col = mod_const.TBL_BG_COLOR
    select_col = mod_const.TBL_SELECT_COLOR
    header_col = mod_const.HEADER_COLOR

    pad_frame = mod_const.FRAME_PAD
    pad = pad if pad else (pad_frame, pad_frame)

    font = font if font else mod_const.LARGE_FONT
    bold_font = mod_const.BOLD_FONT
    font_size = font[1]

    # Arguments
    row_height = mod_const.TBL_ROW_HEIGHT
    width = width
    height = height * 0.5
    nrow = nrow if nrow else int(height / 40)

    # Parameters
    if events and bind:
        bind = False  # only one can be selected at a time
        logger.warning('both bind_return_key and enable_events have been selected during table creation. '
                       'These parameters are mutually exclusive.')

    lengths = mod_dm.calc_column_widths(header, width=width, font_size=font_size, pixels=False)

    if table_name:
        top_layout = [sg.Col([[sg.Text(table_name, pad=(0, 0), font=bold_font, background_color=alt_col)]],
                             justification='c', background_color=header_col, expand_x=True)]
        frame_relief = 'ridge'
    else:
        top_layout = [sg.Canvas(size=(0, 0))]
        frame_relief = 'flat'

    bottom_layout = [sg.Table(data, key=keyname, headings=header, pad=(0, 0), num_rows=nrow,
                              row_height=row_height, alternating_row_color=alt_col, background_color=bg_col,
                              text_color=text_col, selected_row_colors=(text_col, select_col), font=font,
                              display_row_numbers=False, auto_size_columns=False, col_widths=lengths,
                              enable_events=events, bind_return_key=bind, tooltip=tooltip, vertical_scroll_only=False)]

    layout = sg.Frame('', [top_layout, bottom_layout], pad=pad, element_justification='l',
                      vertical_alignment='t', background_color=alt_col, relief=frame_relief)

    return layout

def importer_layout(win_size: tuple = None):
    """
    Create the layout for the database import window.
    """
    if win_size:
        width, height = win_size
    else:
        width, height = (int(mod_const.WIN_WIDTH * 0.9), int(mod_const.WIN_HEIGHT * 0.9))

    # Layout settings
    header_col = mod_const.HEADER_COLOR
    input_col = mod_const.FIELD_BG_COLOR
    bg_col = mod_const.DEFAULT_BG_COLOR
    frame_col = mod_const.FRAME_COLOR
    select_col = mod_const.SELECTED_TEXT_COLOR
    text_col = mod_const.DEFAULT_TEXT_COLOR

    pad_el = mod_const.ELEM_PAD
    pad_v = mod_const.VERT_PAD
    pad_h = mod_const.HORZ_PAD
    pad_frame = mod_const.FRAME_PAD

    font_h = mod_const.HEADING_FONT
    font_bold = mod_const.BOLD_FONT
    font_main = mod_const.MAIN_FONT
    font_large = mod_const.BOLD_HEADING_FONT

    # Keyboard shortcuts
    hotkeys = settings.hotkeys
    cancel_shortcut = hotkeys['-HK_ESCAPE-'][2]
    save_shortcut = hotkeys['-HK_ENTER-'][2]
    next_shortcut = hotkeys['-HK_RIGHT-'][2]
    back_shortcut = hotkeys['-HK_LEFT-'][2]

    # Element sizes
    bwidth = 1
    format_param_w = 14
    frame_w = int(width * 0.85)
    frame_pad = pad_frame * 2
    container_w = frame_w - frame_pad
    subset_w = int(container_w * 0.7)

    try:
        record_types = [i.menu_title for i in settings.records.rules if user.check_permission(i.permissions['upload'])]
    except ValueError:
        record_types = []

    file_types = ['xls', 'csv/tsv']
    encodings = ['Default']

    header_req = ['Record Field', 'Data Type', 'Value']
    header_map = ['Record Field', 'Data Type', 'File Column Name']

    cond_operators = ['=', '!=', '>', '<', '>=', '<=']
    math_operators = ['+', '-', '*', '/', '%', '^', '//']
    def_combo_values = ['', '', '', '', '', '']

    # Window Layout

    # Subset layout
    subset_keys = ['-SUBSET_{}-'.format(i) for i in range(10)]
    subset_layout = [[sg.Canvas(size=(container_w, 0), background_color=bg_col)]]
    for index, subset_key in enumerate(subset_keys):
        oper_key = '-SUBSET_OPER_{}-'.format(index)
        value_key = '-SUBSET_VALUE_{}-'.format(index)
        col_key = '-SUBSET_COL_{}-'.format(index)
        add_key = '-SUBSET_ADD_{}-'.format(index)
        delete_key = '-SUBSET_DELETE_{}-'.format(index)

        if index == 0:  # no delete key
            visible = True
            subset_bttn_layout = [[sg.Button('', key=add_key, image_data=mod_const.ADD_ICON, border_width=1,
                                             button_color=(text_col, bg_col))]]
        elif index == 9:  # no add key
            visible = False
            subset_bttn_layout = [[sg.Button('', key=delete_key, image_data=mod_const.MINUS_ICON, pad=(0, 0),
                                             border_width=1, button_color=(text_col, bg_col))]]
        else:
            visible = False
            subset_bttn_layout = [[sg.Button('', key=delete_key, image_data=mod_const.MINUS_ICON, pad=((0, pad_el), 0),
                                             border_width=1, button_color=(text_col, bg_col)),
                                   sg.Button('', key=add_key, image_data=mod_const.ADD_ICON, border_width=1,
                                             button_color=(text_col, bg_col))]]

        sub_cond_layout = [sg.Col([[sg.Canvas(size=(container_w, 0), background_color=bg_col)],
                                   [sg.Col([[sg.Text('{}.'.format(index + 1), pad=((0, pad_h), 0), font=font_bold,
                                                     background_color=bg_col, auto_size_text=True),
                                             sg.Combo(def_combo_values, key=col_key, pad=((0, pad_h), pad_el),
                                                      size=(int(subset_w * 0.4 / 9), 1), background_color=input_col,
                                                      font=font_main, auto_size_text=False, disabled=True,
                                                      tooltip='Column'),
                                             sg.Combo(cond_operators, key=oper_key, pad=((0, pad_h), pad_el),
                                                      size=(int(subset_w * 0.2 / 9), 1), font=font_bold,
                                                      background_color=input_col, auto_size_text=False, disabled=True,
                                                      tooltip='Operator'),
                                             sg.Input('', key=value_key, pad=((0, pad_el), pad_el),
                                                      size=(int(subset_w * 0.4 / 9), 1), background_color=input_col,
                                                      font=font_main, disabled=True, tooltip='Column value')]],
                                           background_color=bg_col, justification='l', element_justification='l',
                                           expand_x=True),
                                    sg.Col(subset_bttn_layout, pad=(pad_h, 0), justification='r',
                                           element_justification='r', background_color=bg_col)]],
                                  key=subset_key, background_color=bg_col, vertical_alignment='t', justification='l',
                                  element_justification='l', pad=(0, int(pad_el / 2)), visible=visible)
                           ]
        subset_layout.append(sub_cond_layout)

    # Modify layout
    modify_keys = ['-MODIFY_{}-'.format(i) for i in range(10)]
    modify_layout = [[sg.Canvas(size=(container_w, 0), background_color=bg_col)]]
    for index, modify_key in enumerate(modify_keys):
        oper_key = '-MODIFY_OPER_{}-'.format(index)
        value_key = '-MODIFY_VALUE_{}-'.format(index)
        col_key = '-MODIFY_COL_{}-'.format(index)
        add_key = '-MODIFY_ADD_{}-'.format(index)
        delete_key = '-MODIFY_DELETE_{}-'.format(index)

        if index == 0:  # no delete key
            visible = True
            modify_bttn_layout = [[sg.Button('', key=add_key, image_data=mod_const.ADD_ICON, border_width=1,
                                             button_color=(text_col, bg_col))]]
        elif index == 9:  # no add key
            visible = False
            modify_bttn_layout = [[sg.Button('', key=delete_key, image_data=mod_const.MINUS_ICON, pad=(0, 0),
                                             border_width=1, button_color=(text_col, bg_col))]]
        else:
            visible = False
            modify_bttn_layout = [[sg.Button('', key=delete_key, image_data=mod_const.MINUS_ICON, pad=((0, pad_el), 0),
                                             border_width=1, button_color=(text_col, bg_col)),
                                   sg.Button('', key=add_key, image_data=mod_const.ADD_ICON, border_width=1,
                                             button_color=(text_col, bg_col))]]

        mod_cond_layout = [sg.Col([[sg.Canvas(size=(container_w, 0), background_color=bg_col)],
                                   [sg.Col([[sg.Text('{}.'.format(index + 1), pad=((0, pad_h), 0), font=font_bold,
                                                     background_color=bg_col, auto_size_text=True),
                                             sg.Combo(def_combo_values, key=col_key, pad=((0, pad_h), pad_el),
                                                      size=(int(subset_w * 0.4 / 9), 1), background_color=input_col,
                                                      font=font_main, auto_size_text=False, disabled=True,
                                                      tooltip='Column'),
                                             sg.Combo(math_operators, key=oper_key, pad=((0, pad_h), pad_el),
                                                      size=(int(subset_w * 0.2 / 9), 1), font=font_bold,
                                                      background_color=input_col, auto_size_text=False, disabled=True,
                                                      tooltip='Operator'),
                                             sg.Input('', key=value_key, pad=((0, pad_el), pad_el),
                                                      size=(int(subset_w * 0.4 / 9), 1), background_color=input_col,
                                                      font=font_main, disabled=True, tooltip='Column value')]],
                                           background_color=bg_col, justification='l', element_justification='l',
                                           expand_x=True),
                                    sg.Col(modify_bttn_layout, pad=(pad_h, 0), justification='r',
                                           element_justification='r', background_color=bg_col)]],
                                  key=modify_key, background_color=bg_col, vertical_alignment='t', justification='l',
                                  element_justification='l', pad=(0, int(pad_el / 2)), visible=visible)
                           ]
        modify_layout.append(mod_cond_layout)

    # Panel layout
    p1 = [[sg.Col([[sg.Text('File:', size=(5, 1), pad=((0, pad_el), 0), background_color=bg_col),
                    sg.Input('', key='-FILE-', size=(60, 1), pad=(pad_el, 0), background_color=input_col),
                    sg.FileBrowse('Browse ...', pad=((pad_el, pad_frame), 0))]],
                  pad=(pad_frame, (pad_frame, pad_v)), justification='l', background_color=bg_col)],
          [sg.Frame('File format', [
              [sg.Canvas(size=(frame_w, 0), background_color=bg_col)],
              [sg.Col([[sg.Canvas(size=(int(frame_w * 0.15), 0), background_color=bg_col)]],
                      pad=(0, pad_v), background_color=bg_col, expand_x=True, expand_y=True),
               sg.Col([[sg.Canvas(size=(int(frame_w * 0.15), 0), background_color=bg_col)],
                       [sg.Text('Format:', auto_size_text=True, pad=(pad_el, pad_el), background_color=bg_col),
                        sg.Combo(file_types, key='-FORMAT-', default_value='xls', size=(12, 1),
                                 pad=(pad_el, pad_el), background_color=input_col, tooltip='Format of the input file')],
                       [sg.Text('Encoding:', auto_size_text=True, pad=(pad_el, 0), background_color=bg_col),
                        sg.Combo(encodings, key='-ENCODE-', default_value='Default', size=(12, 1), pad=(pad_el, pad_el),
                                 background_color=input_col)]],
                      pad=((pad_h, 0), pad_v), background_color=bg_col, element_justification='r', expand_x=True),
               sg.Col([[sg.Canvas(size=(int(frame_w * 0.15), 0), background_color=bg_col)]],
                      pad=(0, pad_v), background_color=bg_col, expand_x=True, expand_y=True),
               sg.Col([[sg.Canvas(size=(int(frame_w * 0.15), 0), background_color=bg_col)],
                       [sg.Text('Newline Separator:', auto_size_text=True, pad=(pad_el, pad_el),
                                background_color=bg_col),
                        sg.Input('\\n', key='-NSEP-', size=(8, 1), pad=(pad_el, pad_el), disabled=True,
                                 background_color=input_col,
                                 tooltip='Character used in the CSV file to distinguish between rows')],
                       [sg.Text('Field Separator:', auto_size_text=True, pad=(pad_el, pad_el), background_color=bg_col),
                        sg.Input('\\t', key='-FSEP-', size=(8, 1), pad=(pad_el, pad_el), disabled=True,
                                 background_color=input_col,
                                 tooltip='Character used in the CSV file to distinguish between columns')]],
                      pad=((0, pad_h), pad_v), background_color=bg_col, element_justification='r', expand_x=True),
               sg.Col([[sg.Canvas(size=(int(frame_w * 0.15), 0), background_color=bg_col)]], pad=(0, pad_v),
                      background_color=bg_col, expand_x=True, expand_y=True)]
          ], pad=(pad_frame, pad_v), border_width=bwidth, background_color=bg_col, title_color=select_col,
                    relief='groove')],
          [sg.Frame('Formatting options', [
              [sg.Canvas(size=(frame_w, 0), background_color=bg_col)],
              [sg.Checkbox('Recognize dates', key='-DATES-', pad=(pad_h, (pad_v, pad_el)), default=True, font=font_main,
                           background_color=bg_col,
                           tooltip='Attempt to parse the values of columns containing dates.')],
              [sg.Checkbox('Recognize integers', key='-INTS-', pad=(pad_h, pad_el), default=True, font=font_main,
                           background_color=bg_col,
                           tooltip='Attempt to infer whether data type of a column is an integer or float. '
                                   'Excel files store all numeric values as decimals')],
              [sg.Col([[sg.Canvas(size=(int(frame_w * 0.25), 0), background_color=bg_col)],
                       [sg.Text('Skip n rows at top:', auto_size_text=True, pad=(0, pad_el), font=font_main,
                                background_color=bg_col, tooltip='Do not import the first n rows')],
                       [sg.Text('Skip n rows at bottom:', auto_size_text=True, pad=(0, pad_el), background_color=bg_col,
                                font=font_main, tooltip='Do not import the last n rows')],
                       [sg.Text('Header row (0 indexed):', auto_size_text=True, pad=(0, pad_el),
                                background_color=bg_col, font=font_main,
                                tooltip='Row number, starting at 0, containing the column names (applied '
                                        'after filtering by skipped rows).')],
                       [sg.Text('Thousands separator:', auto_size_text=True, pad=(0, pad_el), background_color=bg_col,
                                font=font_main,
                                tooltip='Thousands character used for parsing string columns into a numeric form')],
                       [sg.Text('Date format:', auto_size_text=True, pad=(0, pad_el), background_color=bg_col,
                                font=font_main, tooltip='Date format used by columns containing date values')],
                       [sg.Text('Date offset:', auto_size_text=True, pad=(0, pad_el), background_color=bg_col,
                                font=font_main, tooltip='Dates are offset by the given number of years')]],
                      pad=((pad_h, 0), (0, pad_v)), background_color=bg_col),
               sg.Col([[sg.Canvas(size=(int(frame_w * 0.5), 0), background_color=bg_col)],
                       [sg.Input('0', key='-TSKIP-', size=(format_param_w, 1), pad=(0, pad_el), font=font_main,
                                 background_color=input_col)],
                       [sg.Input('0', key='-BSKIP-', size=(format_param_w, 1), pad=(0, pad_el), font=font_main,
                                 background_color=input_col)],
                       [sg.Input('0', key='-HROW-', size=(format_param_w, 1), pad=(0, pad_el), font=font_main,
                                 background_color=input_col)],
                       [sg.Input(',', key='-TSEP-', size=(format_param_w, 1), pad=(0, pad_el), font=font_main,
                                 background_color=input_col)],
                       [sg.Input('YYYY-MM-DD', key='-DATE_FORMAT-', size=(format_param_w, 1), pad=(0, pad_el),
                                 font=font_main, background_color=input_col)],
                       [sg.Input('0', key='-DATE_OFFSET-', size=(format_param_w, 1), pad=(0, pad_el), font=font_main,
                                 background_color=input_col)]],
                      pad=((0, pad_h), (0, pad_v)), background_color=bg_col, expand_x=True)]
          ],
                    pad=(pad_frame, (pad_v, pad_frame)), border_width=bwidth, background_color=bg_col,
                    title_color=select_col, relief='groove')]]
    p2 = [[sg.Col([[sg.Text('Record Type:', pad=((0, pad_el), 0), background_color=bg_col),
                    sg.Combo(record_types, key='-RECORDTYPE-', size=(28, 1), pad=(0, 0),
                             enable_events=True, background_color=input_col)]],
                  pad=(pad_frame, (pad_frame, pad_v)), justification='l', background_color=bg_col)],
          [sg.Frame('Required Columns', [
              [sg.Canvas(size=(frame_w, 0), background_color=bg_col)],
              [sg.Col([
                  [sg.Col([[sg.Listbox(values=[], key='-REQLIST-', size=(26, 8), font=font_main, bind_return_key=True,
                                       background_color=bg_col, select_mode='extended',
                                       tooltip='Double-click on a column name to add the column to the table')]],
                          background_color=bg_col, justification='l', element_justification='l', expand_x=True),
                   sg.Col([[create_table_layout([[]], header_req, '-REQCOL-', bind=True, pad=(0, 0), nrow=4,
                                                width=width * 0.65,
                                                tooltip='Click on a row to edit the row fields. Use the delete or '
                                                        'backspace keys to remove a row from the table')]],
                          background_color=bg_col, justification='r', element_justification='r')]],
                  pad=(pad_v, pad_v), background_color=bg_col, expand_x=True)]],
                    pad=(pad_frame, pad_v), border_width=bwidth, background_color=bg_col, title_color=select_col,
                    relief='groove', tooltip='Set static values for required import columns.')],
          [sg.Frame('Column Map', [
              [sg.Canvas(size=(frame_w, 0), background_color=bg_col)],
              [sg.Col([
                  [sg.Col([[sg.Listbox(values=[], key='-MAPLIST-', size=(26, 8), font=font_main, bind_return_key=True,
                                       background_color=bg_col, select_mode='extended',
                                       tooltip='Double-click on a column name to add the column to the table')]],
                          background_color=bg_col, justification='l', element_justification='l', expand_x=True),
                   sg.Col([[create_table_layout([[]], header_map, '-MAPCOL-', bind=True, pad=(0, 0), nrow=4,
                                                width=width * 0.65,
                                                tooltip='Click on a row to edit the row fields. Use the delete or '
                                                        'backspace keys to remove a row from the table')]],
                          background_color=bg_col, justification='r', element_justification='r')]],
                  pad=(pad_v, pad_v), background_color=bg_col, expand_x=True)]],
                    pad=(pad_frame, pad_v), border_width=bwidth, background_color=bg_col, title_color=select_col,
                    relief='groove', tooltip='Map imported file column names to database table column names')],
          [sg.Frame('Subset Rows', [
              [sg.Canvas(size=(frame_w, 0), background_color=bg_col)],
              [sg.Col(subset_layout, pad=(pad_v, pad_v), key='-SUBSET-',
                      background_color=bg_col, expand_x=True, expand_y=True,
                      vertical_alignment='t', scrollable=True, vertical_scroll_only=True, justification='l',
                      element_justification='l')]],
                    pad=(pad_frame, pad_v), background_color=bg_col, border_width=bwidth,
                    title_color=select_col, relief='groove', element_justification='l', vertical_alignment='t',
                    tooltip='Use the subset rules to subset table rows based on the values of the imported columns')],
          [sg.Frame('Transform Values', [
              [sg.Canvas(size=(int(width * 0.85), 0), background_color=bg_col)],
              [sg.Col(modify_layout, pad=(pad_v, pad_v), key='-MODIFY-',
                      background_color=bg_col, expand_x=True, expand_y=True,
                      vertical_alignment='t', scrollable=True, vertical_scroll_only=True, justification='l',
                      element_justification='l')]],
                    pad=(pad_frame, (pad_v, pad_frame)), background_color=bg_col, border_width=bwidth,
                    title_color=select_col, relief='groove', element_justification='l', vertical_alignment='t',
                    tooltip='Use the modify rules to modify the values of an imported column. Only date and numeric '
                            'columns support this operation.')]
          ]
    p3 = [[sg.Frame('Import Statistics', [
        [sg.Canvas(size=(frame_w, 0), background_color=bg_col)],
        [sg.Col([
            [sg.Text('Record type:', size=(28, 1), pad=(0, pad_el), background_color=bg_col,
                     font=font_main),
             sg.Text('0', key='-TABLENAME-', size=(12, 1), pad=(0, pad_el), font=font_main,
                     background_color=bg_col)],
            [sg.Text('Number of data columns:', size=(28, 1), pad=(0, pad_el), background_color=bg_col,
                     font=font_main),
             sg.Text('0', key='-NCOL-', size=(12, 1), pad=(0, pad_el), font=font_main,
                     background_color=bg_col)],
            [sg.Text('Number of import rows:', size=(28, 1), pad=(0, pad_el), background_color=bg_col,
                     font=font_main),
             sg.Text('0', key='-NROW-', size=(12, 1), pad=(0, pad_el), font=font_main, background_color=bg_col)
             ]
        ], pad=(pad_v, pad_v), background_color=bg_col, vertical_alignment='t', expand_x=True, expand_y=True)]],
                    pad=(pad_frame, (pad_frame, pad_v)), border_width=bwidth, background_color=bg_col,
                    title_color=select_col, relief='groove')],
          [sg.Frame('Table Preview', [
              [sg.Canvas(size=(frame_w, 0), background_color=bg_col)],
              [sg.Col([
                  [create_table_layout([[]], ['{}'.format(i) for i in range(1)], '-PREVIEW-', pad=(0, 0), nrow=15,
                                       width=width * 0.94, tooltip='Preview of the first 10 and last 10 records that '
                                                                   'will be imported into the database table')]],
                  pad=(pad_v, pad_v), background_color=bg_col, expand_x=True, expand_y=True,
                  element_justification='c', vertical_alignment='c')]],
                    pad=(pad_frame, (pad_v, pad_frame)), border_width=bwidth, background_color=bg_col,
                    title_color=select_col, relief='groove')]]

    panels = [sg.Col(p1, key='-P1-', background_color=bg_col, vertical_alignment='c', visible=True, expand_y=True,
                     expand_x=True),
              sg.Col(p2, key='-P2-', background_color=bg_col, vertical_alignment='c', visible=False, expand_y=True,
                     expand_x=True),
              sg.Col(p3, key='-P3-', background_color=bg_col, vertical_alignment='c', visible=False, expand_y=True,
                     expand_x=True)]

    panel_layout = [[sg.Col([[sg.Canvas(size=(0, height * 0.9), background_color=bg_col)]], background_color=bg_col),
                     sg.Col([[sg.Pane(panels, key='-PANELS-', orientation='horizontal', show_handle=False,
                                      border_width=0, relief='flat')]], pad=(0, pad_v), expand_x=True)]]

    #bttn_layout = [[sg.Button('', key='-BACK-', image_data=mod_const.LEFT_ICON, image_size=mod_const.BTTN_SIZE,
    #                          pad=(pad_el, 0), disabled=True,
    #                          tooltip='Return to previous panel ({})'.format(back_shortcut)),
    #                sg.Button('', key='-NEXT-', image_data=mod_const.RIGHT_ICON, image_size=mod_const.BTTN_SIZE,
    #                          pad=(pad_el, 0), disabled=False,
    #                          tooltip='Move to next panel ({})'.format(next_shortcut)),
    #                sg.Button('', bind_return_key=True, image_data=mod_const.SAVE_ICON, image_size=mod_const.BTTN_SIZE,
    #                          key='-IMPORT-', pad=(pad_el, 0), disabled=True,
    #                          tooltip='Import file contents to the selected database table ({})'.format(save_shortcut)),
    #                sg.Button('', key='-CANCEL-', image_data=mod_const.CANCEL_ICON, image_size=mod_const.BTTN_SIZE,
    #                          pad=(pad_el, 0), disabled=False,
    #                          tooltip='Cancel importing records to the database ({})'.format(cancel_shortcut))]]

    bttn_layout = [[button_layout('-CANCEL-', icon=mod_const.BTTN_CANCEL_ICON, pad=(pad_el, 0), disabled=False,
                                  tooltip='Cancel importing records to the database ({})'.format(cancel_shortcut)),
                    button_layout('-BACK-', icon=mod_const.BTTN_LEFT_ICON, pad=(pad_el, 0), disabled=True,
                                  tooltip='Return to previous panel ({})'.format(back_shortcut)),
                    button_layout('-NEXT-', icon=mod_const.BTTN_RIGHT_ICON, pad=(pad_el, 0), disabled=False,
                                  tooltip='Move to next panel ({})'.format(next_shortcut)),
                    button_layout('-IMPORT-', icon=mod_const.BTTN_SAVE_ICON, disabled=True,
                                  tooltip='Save records to the selected database table ({})'.format(save_shortcut))]]

    sidebar_layout = [
        [sg.Col([[sg.Canvas(size=(0, height * 0.9), background_color=frame_col)]], background_color=frame_col),
         sg.Col([[sg.Text('• ', pad=((pad_frame, pad_el), (pad_frame, pad_el)), font=font_large,
                          background_color=frame_col),
                  sg.Text('File Options', key='-PN1-', pad=((pad_el, pad_frame), (pad_frame, pad_el)),
                          font=font_main, text_color=select_col, background_color=frame_col)],
                 [sg.Text('• ', pad=((pad_frame, pad_el), pad_el), font=font_large, background_color=frame_col),
                  sg.Text('Import Options', key='-PN2-', pad=((pad_el, pad_frame), pad_el), font=font_main,
                          background_color=frame_col)],
                 [sg.Text('• ', pad=((pad_frame, pad_el), pad_el), font=font_large, background_color=frame_col),
                  sg.Text('Data Preview', key='-PN3-', pad=((pad_el, pad_frame), pad_el), font=font_main,
                          background_color=frame_col)]],
                background_color=frame_col, element_justification='l', vertical_alignment='t', expand_y=True)]]

    layout = [[sg.Col([[sg.Text('Import to Database', pad=(pad_frame, (pad_frame, pad_v)),
                                font=font_h, background_color=header_col)]],
                      pad=(0, 0), justification='l', background_color=header_col, expand_x=True, expand_y=True)],
              [sg.Frame('', sidebar_layout, border_width=bwidth, title_color=text_col, relief='solid',
                        background_color=frame_col),
               sg.Frame('', panel_layout, border_width=bwidth, title_color=text_col, relief='solid',
                        background_color=bg_col)],
              [sg.Col(bttn_layout, justification='r', pad=(pad_frame, (pad_v, pad_frame)))]]

    return layout

# Panel layouts
def home_screen(size):
    """
    Create layout for the home screen.
    """
    bg_col = mod_const.FRAME_COLOR
    width, height = size

    layout = sg.Col([[sg.Canvas(key='-HOME_WIDTH-', size=(width, 0), background_color=bg_col)],
                     [sg.Canvas(key='-HOME_HEIGHT-', size=(0, height), background_color=bg_col),
                      sg.Image(filename=settings.logo, background_color=bg_col, key='-HOME_IMAGE-',
                               size=(width, height))]],
                    key='-HOME-', element_justification='c', vertical_alignment='t', background_color=bg_col,
                    expand_y=True, expand_x=True, visible=False)

    return layout


import torch
import torchvision
from torchvision import datasets, transforms
from torch.autograd import Variable
import matplotlib.pyplot as plt

transform = transforms.Compose([transforms.ToTensor(),
                                # transforms.Lambda(lambda x: x.repeat(3,1,1)),
                                # 而是因为图片格式是灰度图只有一个channel，需要变成RGB图才可以
                                # transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))
                                # transforms.Normalize((0.1307,), (0.3081,))
                                transforms.Normalize([0.5],[0.5])
])

print("downloading datasets")
data_train = datasets.MNIST(root = "../data/", transform = transform, train=True, download=True)
data_test = datasets.MNIST(root = "../data/", transform = transform, train=False)
print("finished downloading")

data_loader_train = torch.utils.data.DataLoader(dataset = data_train,
                                                batch_size = 64,
                                                shuffle = True)
data_loader_test = torch.utils.data.DataLoader(dataset = data_test,
                                               batch_size = 64,
                                               shuffle = True)

images,labels = next(iter(data_loader_train))
img = torchvision.utils.make_grid(images)
img = img.numpy().transpose(1,2,0)
std = [0.5,0.5,0.5]
mean = [0.5,0.5,0.5]
img = img*std+mean
print([labels[i] for i in range(64)])
plt.imshow(img)
plt.show()

class RNN(torch.nn.Module):
  def __init__(self):
    super(RNN, self).__init__()
    self.rnn = torch.nn.RNN(
      input_size = 28,
      # 用于指定输入数据特征数，因为输入图片都是28 x 28的
      hidden_size = 128,
      # 隐藏层输出特征数
      num_layers = 1,
      # 循环层堆叠的数量，默认是1
      batch_first = True
      # 默认是（seq,batch,feature）
      # 如果设置为True，会设置成：
      # （batch,seq,featrue）
    )
    self.output = torch.nn.Linear(128, 10)
    # self.output = torch.nn.Linear(192,10)
    # output是10，有10个分类
    # 隐藏层的输出代表input，128

  def forward(self, input):
    # torch.Size([192, 28, 28])
    output,_ = self.rnn(input,None)
    # H^0一般采用0初始化，所以H^0这里设置到None
    output = self.output(output[:,-1,:])
    # 提取最后一个序列的输出结果作为当前循环神经网络模型的输出。
    return output

model = RNN()

# 接下来进行训练，进行10个epoch
optimizer = torch.optim.Adam(model.parameters())
loss_func = torch.nn.CrossEntropyLoss()

epoch_n = 10
for epoch in range(epoch_n):
  running_loss = 0.0
  running_correct = 0.0
  testing_correct = 0.0
  print("Epoch {}/{}".format(epoch,epoch_n))
  print("-"*50)

  # 训练集
  for data in data_loader_train:
    X_train, y_train = data
    X_train = X_train.view(-1,28,28)
    # 默认设置H^0为0，28x28的图片大小
    X_train, y_train = Variable(X_train), Variable(y_train)
    y_pred = model(X_train)
    loss = loss_func(y_pred, y_train)
    _, pred = torch.max(y_pred.data, 1)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    running_loss += loss.item()
    running_correct += torch.sum(pred == y_train.data)

  # 测试集
  for data in data_loader_test:
    X_test, y_test = data
    X_test = X_test.view(-1, 28, 28)
    X_test, y_test = Variable(X_test), Variable(y_test)
    outputs = model(X_test)
    _, pred = torch.max(outputs.data, 1)
    testing_correct += torch.sum(pred == y_test.data)
  print("Loss is: {:.4f}, Training Accuracy: {:.4f}%, Test Accuracy: {:.4f}"
      .format(running_loss/len(data_train), 100*running_correct/len(data_train),
              100*testing_correct/len(data_test)))


from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import logging
from scipy.ndimage import fourier_shift
import numpy as np
import operator
import dxchange
import gc

logger = logging.getLogger(__name__)

__author__ = ['Rafael Vescovi', 'Ming Du']
__credits__ = "Doga Gursoy"
__copyright__ = "Copyright (c) 2015, UChicago Argonne, LLC."
__docformat__ = 'restructuredtext en'
__all__ = ['realign_image',
           'realign_block',
           'vig_image',
           'arrange_image',
           'sino_360_to_180',
           'get_roughshift']

def arrange_image(img1, img2, shift, order=1, trim=True):
    """
    Place properly aligned image in buff

    Parameters
    ----------
    img1 : ndarray
        Substrate image array.

    img2 : ndarray
        Image being added on.

    shift : float
        Subpixel shift.
    order : int
        Order that images are arranged. If order is 1, img1 is written first and img2 is placed on the top. If order is
        2, img2 is written first and img1 is placed on the top.
    trim : bool
        In the case that shifts involve negative or float numbers where Fourier shift is needed, remove the circular
        shift stripe.

    Returns
    -------
    newimg : ndarray
        Output array.
    """
    rough_shift = get_roughshift(shift).astype('int')
    adj_shift = shift - rough_shift.astype('float')
    if np.count_nonzero(np.isnan(img2)) > 0:
        logger.debug('Skipping subpixel because of nan presence.')
        int_shift = np.round(adj_shift).astype('int')
        img2 = np.roll(np.roll(img2, int_shift[0], axis=0), int_shift[1], axis=1)
    else:
        img2 = realign_image(img2, adj_shift)
    if trim:
        temp = np.zeros(np.array(img2.shape) - np.ceil(np.abs(adj_shift)).astype('int'))
        temp[:, :] = img2[:temp.shape[0], :temp.shape[1]]
        img2 = np.copy(temp)
        temp = 0
    new_shape = np.array(img2.shape) + np.array(rough_shift)
    new_shape = np.max(np.array([new_shape, img1.shape]), axis=0).astype('int')
    # new_shape = map(int, map(max, map(operator.add, img2.shape, rough_shift), img1.shape))
    newimg = np.empty(new_shape)
    newimg[:, :] = np.NaN
    if order == 1:
        newimg[0:img1.shape[0], 0:img1.shape[1]] = img1
        notnan = np.isfinite(img2)
        newimg[rough_shift[0]:rough_shift[0] + img2.shape[0], rough_shift[1]:rough_shift[1] + img2.shape[1]][notnan] \
            = img2[notnan]
    elif order == 2:
        newimg[rough_shift[0]:rough_shift[0] + img2.shape[0], rough_shift[1]:rough_shift[1] + img2.shape[1]] = img2
        notnan = np.isfinite(img1)
        newimg[0:img1.shape[0], 0:img1.shape[1]][notnan] = img1[notnan]
    else:
        print('Warning: images are not arranged due to misspecified order.')
    gc.collect()
    if trim:
        return newimg, img2
    else:
        return newimg

def realign_image(arr, shift, angle=0):
    """
    Translate and rotate image via Fourier

    Parameters
    ----------
    arr : ndarray
        Image array.

    shift: float
        Mininum and maximum values to rescale data.

    angle: float, optional
        Mininum and maximum values to rescale data.

    Returns
    -------
    ndarray
        Output array.
    """
    # if both shifts are integers, do circular shift; otherwise perform Fourier shift.
    if np.count_nonzero(np.abs(np.array(shift) - np.round(shift)) < 0.01) == 2:
        temp = np.roll(arr, int(shift[0]), axis=0)
        temp = np.roll(temp, int(shift[1]), axis=1)
        temp = temp.astype('float32')
    else:
        temp = fourier_shift(np.fft.fftn(arr), shift)
        temp = np.fft.ifftn(temp)
        temp = np.abs(temp).astype('float32')
    return temp

def realign_block(arr, shift_vector, angle_vector=None, axis=0):
    """
    Translate and rotate image via Fourier

    Parameters
    ----------
    arr : ndarray
        Image array.

    shift: float, optional
        Mininum and maximum values to rescale data.

    angle: float, optional
        Mininum and maximum values to rescale data.

    Returns
    -------
    ndarray
        Output array.
        :param arr:
        :param shift_vector:
        :param angle_vector:
        :param axis:
    """

def get_roughshift(shift):

    rough_shift = np.ceil(shift)
    rough_shift[rough_shift < 0] = 0
    return rough_shift

def vig_image(img, vig=150):
    temp = np.copy(img)
    if img.ndim is 3:
        for i in range(img.shape[0]):
            temp[i, :, :] = vig_2d(temp[i, :, :], vig=vig)
    else:
        temp = vig_2d(temp, vig=vig)
    return temp

def vig_2d(img, vig=150):
    temp = np.copy(img)
    step = 1.0 / vig
    for k in np.arange(vig):
        pos = vig - k
        temp[pos, :] = temp[pos, :] * step * pos
        temp[-pos, :] = temp[-pos, :] * step * pos
        temp[:, pos] = temp[:, pos] * step * pos
        temp[:, -pos] = temp[:, -pos] * step * pos
    return temp

def test_out(img, save_folder):
    img[np.abs(img) < 1e-3] = 1e-3
    img[img > 1] = 1
    img = -np.log(img)
    img[np.where(np.isnan(img) == True)] = 0
    dxchange.write_tiff(np.squeeze(img), fname=save_folder + 'test')

def sino_360_to_180(data, overlap=0, rotation='left'):
    """
    Converts 0-360 degrees sinogram to a 0-180 sinogram.
    If the number of projections in the input data is odd, the last projection
    will be discarded.
    Parameters
    ----------
    data : ndarray
        Input 3D data.
    overlap : scalar, optional
        Overlapping number of pixels.
    rotation : string, optional
        Left if rotation center is close to the left of the
        field-of-view, right otherwise.
    Returns
    -------
    ndarray
        Output 3D data.
    """
    dx, dy, dz = data.shape

    overlap = int(np.round(overlap))

    lo = overlap//2
    ro = overlap - lo
    n = dx//2

    out = np.zeros((n, dy, 2*dz-overlap), dtype=data.dtype)

    if rotation == 'left':
        out[:, :, -(dz-lo):] = data[:n, :, lo:]
        out[:, :, :-(dz-lo)] = data[n:2*n, :, ro:][:, :, ::-1]
    elif rotation == 'right':
        out[:, :, :dz-lo] = data[:n, :, :-lo]
        out[:, :, dz-lo:] = data[n:2*n, :, :-ro][:, :, ::-1]

    return out


# coding:utf-8

'''
funword -- 单词操作函数公用单元
Created on 2010-9-2
@author: tongjp

findword() 根据搜素关键词返回查询结果
pageword() 以分页的形式返回单词查询结果，最多3000条记录
pagenword() 以分页的形式返回生词词查询结果
'''

from django.core.paginator import *
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.db.models import Max,Q

from jpstudy.sysfunc import addtestval
from jpstudy.sysfunc.commfunc import makecode
from dictdata.models import JaWord,MaxNo,JaGroup

# 查询单词
def findword(vword):
        jwordlist = JaWord.objects.filter(Q(fword=vword)|Q(fpronunciation=vword))
        if jwordlist:
            return jwordlist
        else:
            return None

# 返回单词列表
def pageword(request):
    results=JaWord.objects.all()[:3000]
    paginator=Paginator(results,10)
    # 确信Request要求是个整数，负责返回1
#    assert False
    try:
        try:
            page = int(request.POST.get('pageno'))
        except:
            page = int(request.GET.get('page', '1'))
#        if (request.POST.get('pageno')).isdigit():
#            page = int(request.POST.get('pageno', '1'))
#        else:

    except ValueError:
        page = 1
    # 如果页码要就超出范围，返回最后一页
    try:
        wordlist = paginator.page(page)
    except (EmptyPage, InvalidPage):
        wordlist = paginator.page(paginator.num_pages)

    return wordlist

# 日语单词导入新表
def jaotonew(vword):
    jwordlist = JaWord.objects.exclude(fuser='tongjp')[:500]
    for jword in jwordlist:
        jword.fuser = 'tongjp'
        jword.save()
    return HttpResponseRedirect("/")

# 日语单词导回
def newbackold(vword):
    jwordlist = JaWord.objects.exclude(fuser='tongjp')
    jwordlist.update(fuser='tongjp')
    return HttpResponseRedirect("/")

# 日语单词导入新表
def delwgroup(requst):
    jwgrouplist = JaGroup.objects.all()
    jwgrouplist.delete()
    return HttpResponseRedirect("/")

# 获取最大单词号
def getmaxno(request):
    results = JaWord.objects.all().order_by('-fwordno')[:1]
    maxno = results.get()
    return HttpResponseRedirect(maxno.fwordno)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('scenic', '0059_census_dev'),
    ]

    operations = [
        migrations.RenameField(
            model_name='census',
            old_name='Dev',
            new_name='dev',
        ),
        migrations.AlterField(
            model_name='census',
            name='date',
            field=models.DateTimeField(auto_now=True, null=True),
        ),
    ]


# -*- coding: utf-8 -*-
"""
Created on Sat Nov 20 21:48:17 2021

@author: vonGostev
"""
import __init__
import numpy as np
import cupy as cp
import matplotlib.pyplot as plt
from lightprop2d import Beam2D, um, gaussian_beam
from scipy.sparse.linalg import expm
from scipy.sparse import csc_matrix

npoints = 256
cradius = 31.25
mod_radius = cradius / 2
area_size = cradius * 3.5
wl = 0.632
distances = [0, 100 * um, 1000 * um, 1]
bounds = [- area_size / 2, area_size / 2]
# loaded_data = np.load('smf_SI_3_properties.npz')
# loaded_data = np.load('mmf_SI_50_properties.npz')
loaded_data = np.load('mmf_GRIN_62.5_properties.npz')
modes = loaded_data['modes_list']
OP = csc_matrix(loaded_data['fiber_op'])
ibeam = Beam2D(
    area_size=area_size * um, npoints=npoints, wl=wl * um,
    init_field_gen=gaussian_beam,
    init_gen_args=(1, mod_radius * um,),
    use_gpu=True)
# init_field_gen=round_hole, init_gen_args=(cradius,))
profiles = [ibeam.iprofile]

mc = ibeam.deconstruct_by_modes(modes)
ibeam.construct_by_modes(modes, mc)
# ibeam.expand(ibeam.area_size * 2)

profiles.append(ibeam.iprofile)

mc = cp.array(expm(1j * OP * 10.).todense()) @ mc

for d in distances:
    ibeam.construct_by_modes(modes, mc)
    ibeam.propagate(d)
    profiles.append(ibeam.iprofile)
    ibeam.expand(ibeam.area_size * 2)
    ibeam.coarse(2)

fig, ax = plt.subplots(2, 3, figsize=(9, 6))
axes = ax.flatten()

i = 0
lbl = 'abcdef'
for ax, p in zip(axes, profiles):
    if i < 3:
        ax.imshow(p, extent=bounds*2)
    else:
        ax.imshow(p, extent=[- area_size / 2 * (i - 1),
                             area_size / 2 * (i - 1)]*2)
    ax.set_xlabel(f'({lbl[i]})')
    i += 1
plt.tight_layout()
plt.savefig('mmf/mmf_grin_gaussian_ip.png', dpi=100)
plt.show()

loaded_data.close()


__author__ = 'Zhiyang Ong'
__version__ = '0.1'
__date__ = 'February 25, 2025'

###############################################################

"""
	Import modules from The Python Standard Library.
	sys			Get access to any command-line arguments.
	os			Use any operating system dependent functionality.
	os.path		For pathname manipulations.

	subprocess -> call
				To make system calls.
	time		To measure elapsed time.
	warnings	Raise warnings.
	re			Use regular expressions.
	filecmp		For file comparison.
	datetime	For operations regarding date and time.
"""

import sys
import os
import os.path
from subprocess import call
import time
import warnings
import re
import filecmp
import datetime

###############################################################

#	Import Python Modules from installed Python packages, via PyPI

# Requires the following installation.
#pip install bibtexparser
# Import [Boulogne2022] [Boulogne2023a]
#import bibtexparser

###############################################################

#	Import Custom Python Modules

# Module to process input arguments to the script/program.
#from utilities.queue_ip_arguments import queue_ip_args
# Module to perform file I/O (input/output) operations.
#from utilities.file_io import file_io_operations

# Module for timing measurements.
from timing_measurements.performance_measurement_no_ns import execution_time_measurement_no_ns

###############################################################
# Main method for the program.

#	If this is executed as a Python script,
if __name__ == "__main__":
	#	= Set up loading of BibTeX database
	# Type of current time measurement.
	mode_current_time_measurement = "perf_counter"
	# Set the initial timestamp.
	execution_time_measurement_no_ns.set_initial_timestamp()
	"""
		Filename/path of the output file that contains the extracted BibTeX entries.
	"""
	output_filename = "./output-files/extracted_bibtext_entries.bib"
	# --------------------------------------------------------
	"""
		Check if the output filename is valid [DrakeJr2023a, from Generic Operating System Services: os — Miscellaneous operating system interfaces: Files and Directories].

		https://docs.python.org/3/library/os.html#os.access
		https://docs.python.org/3/library/os.html#os.W_OK
	"""
	if os.access(output_filename, os.W_OK):
		print("	Filename/Path to target output filename is valid:",output_filename,"=")
	else:
		print(">>>	Filename/Path to target output filename is invalid:",output_filename,"=")
		"""
			Get the absolute path containing the target output file.

			https://docs.python.org/3/library/os.path.html#os.path.abspath
		"""
		absolute_path_of_target_output_file = os.path.abspath(output_filename)
		print("	Path of target output:",absolute_path_of_target_output_file,"=")
		"""
			This approach only grabs the filename.
		path_of_directory_for_target_output_file = os.path.basename(output_filename)
		print("	Path of the directory for target output:",path_of_directory_for_target_output_file,"=")
		"""
		"""
			Get the path of the directory that would contain the target output file.

			https://docs.python.org/3/library/os.path.html#os.path.dirname
		"""
		path_of_directory_for_target_output_file = os.path.dirname(absolute_path_of_target_output_file)
		print("	Path of the directory for target output:",path_of_directory_for_target_output_file,"=")
		"""
			Is directory that would contain output file a valid directory?

			https://docs.python.org/3/library/os.path.html#os.path.isdir
		"""
		if os.path.isdir(path_of_directory_for_target_output_file):
			print("	Path of the directory for target output is valid.")
			print("	Target output file can be created.")
		else:
			print("	Path of the directory for target output is INVALID!!!")
			print("	Target output file cannot be created!!!")
			print("	Please kindly select path for output file in an existing directory!!!")
	output_filename = "./non-existent-directory/random_bibtex_database_non_existent.bib"
	if os.access(output_filename, os.W_OK):
		print("	Filename/Path to target output filename is valid:",output_filename,"=")
	else:
		print(">>>	Filename/Path to target output filename is invalid:",output_filename,"=")
		absolute_path_of_target_output_file = os.path.abspath(output_filename)
		print("	Path of target output:",absolute_path_of_target_output_file,"=")
		path_of_directory_for_target_output_file = os.path.dirname(absolute_path_of_target_output_file)
		print("	Path of the directory for target output:",path_of_directory_for_target_output_file,"=")
		if os.path.isdir(path_of_directory_for_target_output_file):
			print("	Path of the directory for target output is valid.")
			print("	Target output file can be created.")
		else:
			print("	Path of the directory for target output is INVALID!!!")
			print("	Target output file cannot be created!!!")
			print("	Please kindly select path for output file in an existing directory!!!")
	output_filename = "./output-files/z-empty-file.md"
	if os.access(output_filename, os.W_OK):
		print(">>>	Filename/Path to target output filename is valid:",output_filename,"=")
	else:
		print(">>>	Filename/Path to target output filename is invalid:",output_filename,"=")
	# --------------------------------------------------------
	# Get the elapsed time.
	elapsed_time = execution_time_measurement_no_ns.get_elapsed_time(mode_current_time_measurement)
	#temp_text = "Elapsed time:::"+str(datetime.timedelta(seconds=elapsed_time))+"=\n"
	print("Elapsed time:::",datetime.timedelta(seconds=elapsed_time),"=")


import numpy as np
import matplotlib.pyplot as plt
import nltk
import textrank

from random import shuffle
from postprocessing import Postprocess
from preprocessing import Preprocessing
from text_cnn import TextCNN
from extension import Extension
from plotting import Plotting

class Main(object):
    """
    Runs the main functions of the system in order,
    collecting the summary results.
    """

    def __init__(self):
        self.pre = None
        self.post = None

    def load_dataset(self, stem):
        # Loads and reads in data files

        print("initialising training models...")

        self.pre = Preprocessing(stem)
        self.post = Postprocess(self.pre)

        print("reading files...")

        self.pre.read_files()

        assert(self.pre is not None)
        assert(self.post is not None)

    def text_rank(self):
        test_entries = self.pre.test_entries
        textrank.TextRank.run(test_entries)

    def extension(self):
        test_entries = self.pre.test_entries
        Extension(test_entries)

    def control_case(self):
        test_entries = self.pre.test_entries

        def get_summary_sentences(word_count, list):

            count = word_count
            summary = ""
            for sent in list:
                if count < 0:
                    break
                else:
                    index = None
                    for i in range(len(sent)):
                        if sent[i].isalnum():
                            index = i
                            break
                    new_sent = sent[index:]
                    length = len(nltk.word_tokenize(new_sent))
                    summary += new_sent + " "
                    count -= length

            return summary

        for e in test_entries:
            sentences = e.sentences
            new_sentences = sentences[:]  # Copy sentences
            shuffle(new_sentences)
            summary = get_summary_sentences(100, new_sentences)
            assert(summary is not None)
            e.control_sum = summary

    @staticmethod
    def digit_count(entries):
        # Counts number of digits present in all entries

        cnn_dig_count = 0
        tr_dig_count = 0
        for entry in entries:
            cnn_dig_count += sum(c.isdigit() for c in entry.generated_sum)
            tr_dig_count += sum(c.isdigit() for c in entry.text_rank_sum)
        print("CNN dig count= ", cnn_dig_count)
        print("TextRank dig count= ", tr_dig_count)

    def main(self):
        # Runs all preprocessing and evaluations to collect results

        print("loading datasets...")
        self.load_dataset(stem=False)
        print("running control case model...")
        self.control_case()
        print("running TextRank model...")
        self.text_rank()
        print("running CNN model...")
        self.cnn(train=False)
        print("running extension")
        self.extension()

        print("calculating rouge scores...")

        self.post.calculate_rouge(0.5)
        self.digit_count(self.pre.test_entries)

        # Prints three example summaries
        for x in range(3):
            print("CNN summary: ", self.pre.test_entries[x].generated_sum)
            print("TextRank summary: ", self.pre.test_entries[x].text_rank_sum)
            print("Combined summary: ", self.pre.test_entries[x].combined_sum)
            print("Gold Standard summary: ", self.pre.test_entries[x].summary)
            print("Doc ID: ",self.pre.test_entries[x].doc_id)
            print()

        plotter = Plotting(self.pre.test_entries)
        plotter.plot()

    def cnn(self, train):
        # Trains or loads CNN depending on train = True/False

        if train:
            print("getting initial salience scores...")
            self.pre.get_salience_scores(load=True)

            train_data, train_labels, _ = self.pre.get_cnn_vectors(train)

            assert(train_data is not None and train_labels is not None)

            # We've now pre process the documents, so now we can feed into the CNN

            TextCNN(train_data=train_data, train_labels=train_labels, num_filters=400, kernel_size=3)
            exit()
        else:
            _, _, test_data = self.pre.get_cnn_vectors(train)

            print("generating salience results...")

            gen_salience_results = TextCNN.eval(test_data)
            print(gen_salience_results)

            print("post-processing results...")
            self.post.get_results(gen_salience_results)

            print("getting summaries...")

            self.post.get_summary_sentences(100)
            self.post.return_summaries()

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


# 2020.03.10-Homework-kamene ping
from kamene.all import *
from kamene.layers.inet import IP, ICMP
import logging

logging.getLogger('kamene.runtime').setLevel(logging.ERROR)

def qytang_ping(ip):
    ping_pkt = IP(dst=ip) / ICMP()
    ping_result = sr1(ping_pkt, timeout=2, verbose=False)

    if ping_result:
        return ip, 1
    else:
        return ip, 0

if __name__ == '__main__':
    result = qytang_ping('192.168.200.3')  # Linux VM， ping自己的ip地址就不通，shell是可以通的，不知道是为啥？？？
    if result[1]:
        print(result[0], '通')
    else:
        print(result[0], '不通')


# -*- coding: utf-8 -*-
"""
data access

@author: hch
@date  : 2021/12/8
"""
from pymongo import MongoClient
import redis

from conf.config import APP_CONF

class MongoDao:
    def __init__(self):
        self.client = MongoClient(APP_CONF.mongodb.conn)
        self.db = self.client.get_database('wx_chat_bot')

    def log_msg(self, msg):
        self.db.get_collection('msg').insert_one({
            '_id': msg.msgId,
            'content': msg.content,
            'from_user_nick_name': msg.user.nickName,
            'from_user_name': msg.fromUserName,
            'to_user_name': msg.toUserName,
            'create_time': msg.createTime,
        })

class RedisDao:
    pool = redis.ConnectionPool(decode_responses=True)
    r = redis.Redis(connection_pool=pool, decode_responses=True)

if __name__ == '__main__':
    dao = MongoDao()
    print(dao.client.get_database('wx_chat_bot').get_collection('msg').find_one())


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script to parse the mapping results of KMA, when the ref database is a set of VAMB bins

Created on 5/3/21
@author: V.R.Marcelino
"""

import pandas as pd
from argparse import ArgumentParser
import os

parser = ArgumentParser()
parser.add_argument('-i', '--input_fp', help="""Path to the folder containing KMA res files.""", required=True)
parser.add_argument('-o', '--output_fp', default = 'merged_samples.csv',
                    help='Path to the output file. Default = merged_samples', required=False)

args = parser.parse_args()
in_folder = args.input_fp
output = args.output_fp

#in_folder = "01_KMA"
#output = "merged_samples.csv"

### define how we will aggregate the info
f4agg = {}
f4agg['Depth']= 'sum'
f4agg['Taxonomy']= 'first'

# create new dataframe to store all samples:
all_samples = pd.DataFrame()

# read input files and merge results
for file in os.listdir(in_folder):
    if file.endswith(".res"):
        sample_name = file.split("_mags.res")[0]
        result_fp = os.path.join(in_folder, file)
        out_sample_fp = result_fp + ".summary.csv"

        df = pd.read_csv(result_fp, sep='\t', encoding='latin1')

        # Make 3 new columns for binID, contigIDs and taxonomy
        df[["BinID","contigID","Taxonomy"]] = df["#Template"].str.split('|', expand=True)

        depth_by_tax = df.groupby(by="BinID").agg(f4agg)
        depth_by_tax.rename(columns={'Depth': sample_name}, inplace=True)

        #save this file for reference
        pd.DataFrame.to_csv(depth_by_tax, out_sample_fp, index=True)

        all_samples = pd.concat([all_samples, depth_by_tax], sort=True, axis=1)

# Group taxon ranks
all_samples = all_samples.groupby(by=all_samples.columns, axis = 1).first()

# Fill NaN with zeros:
all_samples = all_samples.fillna(0)

# Save to file
pd.DataFrame.to_csv(all_samples, output, index=True)


#!/usr/bin/env python3

"""Sample program which shows how to talk to a bioloid servo."""

import argparse
import os
import sys
import serial
import logging
import time

from bioloid.serial_bus import SerialPort, SerialBus
from bioloid.device_type_parser import DeviceTypeParser
from bioloid.device_type import DeviceTypes
from bioloid.device import Device
from bioloid.log_setup import log_setup

def main():
    default_baud = 1000000
    default_port = os.getenv("BIOLOID_PORT")
    parser = argparse.ArgumentParser(
        prog="bioloid",
        usage="%(prog)s [options] [command]",
        description="Send commands to bioloid devices",
        epilog=("You can specify the default serial port using the " +
                "BIOLOID_PORT environment variable.")
    )
    parser.add_argument(
        "-b", "--baud",
        dest="baud",
        action="store",
        type=int,
        help="Set the baudrate used (default = %d)" % default_baud,
        default=default_baud
    )
    default_port_help = ""
    if default_port:
        default_port_help = " (default '%s')" % default_port
    parser.add_argument(
        "-p", "--port",
        dest="port",
        help="Set the serial port to use" + default_port_help,
        default=default_port
    )
    parser.add_argument(
        "-i", "--id",
        dest="dev_id",
        type=int,
        help="Sets the id of the servo to use",
        default=1
    )
    parser.add_argument(
        "-d", "--debug",
        dest="debug",
        action="store_true",
        help="Enable debug features",
        default=False
    )
    args = parser.parse_args(sys.argv[1:])
    script_dir = os.path.dirname(os.path.realpath(__file__))

    log_setup()
    log = logging.getLogger()
    if args.debug:
        log.setLevel(logging.DEBUG)

    if not args.port:
        log.error("No serial port specified")
        sys.exit(1)

    log.info("Port = %s", args.port)
    log.info("Baud = %d", args.baud)
    log.info("ID   = %d", args.dev_id)

    dev_types = DeviceTypes()
    parser = DeviceTypeParser(dev_types)
    parser.parse_dev_type_files(script_dir)
    try:
        serial_port = SerialPort(port=args.port, baudrate=args.baud)
    except serial.serialutil.SerialException:
        log.error("Unable to open port '%s'", args.port)
        sys.exit(1)
    bus = SerialBus(serial_port, show_packets=args.debug)

    servo_type = dev_types.get("servo")
    if not servo_type:
        log.error("Unable to find device type 'servo'")
        sys.exit(1)
    dev = Device(bus, args.dev_id, servo_type)
    if not dev.ping():
        log.error("Device %d doesn't seem to be responding", args.dev_id)
        sys.exit(1)

    led = dev.get_dev_reg("led")
    goal_position = dev.get_dev_reg("goal-position")
    moving_speed = dev.get_dev_reg("moving-speed")

    moving_speed.set(20)
    log.info("Speed = %.1f", moving_speed.get())

    try:
        for _ in range(10):
            log.info("led on - position 0")
            led.set(1)
            goal_position.set(0)
            time.sleep(2)
            log.info("led off - position 100")
            led.set(0)
            goal_position.set(300)
            time.sleep(2)
    except KeyboardInterrupt:
        pass

main()


import tensorflow as tf
from sparkflow.tensorflow_async import SparkAsyncDLModel
from google.protobuf import json_format
from pyspark.ml.pipeline import PipelineModel
import json

def load_tensorflow_model(
        path,
        inputCol,
        tfInput,
        tfOutput,
        predictionCol='predicted',
        tfDropout=None,
        toKeepDropout=False):
    with tf.Session(graph=tf.Graph()) as sess:
        new_saver = tf.train.import_meta_graph(path + '.meta')
        split = path.split('/')
        if len(split) > 1:
            new_saver.restore(sess, tf.train.latest_checkpoint("/".join(split[:-1])))
        else:
            new_saver.restore(sess, tf.train.latest_checkpoint(split[0]))
        vs = tf.trainable_variables()
        weights = sess.run(vs)
        json_graph = json_format.MessageToJson(tf.train.export_meta_graph())

    weights = [w.tolist() for w in weights]
    json_weights = json.dumps(weights)
    return SparkAsyncDLModel(
        inputCol=inputCol, modelJson=json_graph, modelWeights=json_weights,
        tfInput=tfInput, tfOutput=tfOutput, predictionCol=predictionCol, tfDropout=tfDropout, toKeepDropout=toKeepDropout
    )

def attach_tensorflow_model_to_pipeline(
        path,
        pipelineModel,
        inputCol,
        tfInput,
        tfOutput,
        predictionCol='predicted',
        tfDropout=None,
        toKeepDropout=False ):
    spark_model = load_tensorflow_model(path, inputCol, tfInput, tfOutput, predictionCol, tfDropout, toKeepDropout)
    return PipelineModel(stages=[pipelineModel, spark_model])


# -*- coding: utf-8 -*-
"""
Created on Tue Feb 28 16:34:19 2017

@author: kurner
"""

import os
import os.path
import requests
import xml.etree.ElementTree as ET

PROJECT = "/Users/kurner/Downloads/session10"

if not os.path.abspath(".") != PROJECT:
    os.chdir(PROJECT)

#get_url = ("https://developer.trimet.org/ws/V1/trips/tripplanner/"
#           "fromplace/pdx/toplace/zoo/appId/8....")

#r = requests.get(get_url)
#print(dir(r))
#print(r.status_code)
#print(r.text)

ns = {"model":"http://maps.trimet.org/maps/model/xml"}

# root =  ET.fromstring(r.text)

tree = ET.parse("trimet_trip_plan.xml")
root = tree.getroot()

itineraries = root.findall("model:itineraries", ns)

for itinerary in itineraries[0].findall("model:itinerary", ns):
    td = itinerary.find("model:time-distance", ns)
    date  = td.find("model:date", ns).text
    start = td.find("model:startTime", ns).text
    end = td.find("model:endTime", ns).text
    duration = td.find("model:duration", ns).text
    distance = td.find("model:distance", ns).text
    print("----")
    print("Date:", date)
    print("Start Time:", start)
    print("End Time:", end)
    print("Duration:", duration)
    print("Distance:", distance)

    for idx, leg in enumerate(itinerary.findall("model:leg", ns)):
        print("Leg ", idx)
        mode = leg.attrib['mode']
        leg_start, leg_end = "", ""

        td = False
        td = leg.find("model:time-distance", ns)
        if td and mode !="Walk":
            leg_start = td.find("model:startTime", ns).text
            leg_end   = td.find("model:endTime", ns).text

        start_from = leg.find("model:from", ns)
        start_stopId = start_from.find("model:stopId", ns).text
        start_dest = start_from.find("model:description", ns).text

        end_at = leg.find("model:to", ns)
        if mode != "Walk":
            end_stopId = end_at.find("model:stopId", ns).text
            route = leg.find("model:route", ns).find("model:name", ns).text
        else:
            end_stopId = "N/A"
            route = "On foot"
        end_dest = end_at.find("model:description", ns).text

        print("Mode : {}".format(route))
        print("Start: {:8} {:>8} {}".format(leg_start, start_stopId, start_dest))
        print("End  : {:8} {:>8} {}".format(leg_end, end_stopId, end_dest))


import torch
import torch.nn as nn
import numpy as np
import pickle

iteration_num = 250
class MLPModel(nn.Module):
    # I defined the hyperparameters. These are in the parameters of the init function.
    def __init__(self,number_of_hidden_layers,number_of_neurons,learning_rate,activation_function,epoch):
        # I initialized the parameters.
        super(MLPModel,self).__init__()
        self.layer1 = None
        self.layer2 = None
        self.layer3 = None
        self.learning_rate = learning_rate
        self.number_of_hidden_layers = number_of_hidden_layers
        self.number_of_neurons = number_of_neurons
        self.activation_function = activation_function
        self.epoch = epoch
        self.hidden_layer_output = None
        self.hidden_layer_output_2 = None
        self.output_layer = None
        # Since there are two options of the hidden layer, we have to handle this situation in the two different block.
        if number_of_hidden_layers == 1:
            self.layer1 = nn.Linear(784,number_of_neurons)
            self.layer2 = nn.Linear(number_of_neurons,10)
        if number_of_hidden_layers == 2:
            self.layer1 = nn.Linear(784,number_of_neurons)
            self.layer2 = nn.Linear(number_of_neurons,number_of_neurons)
            self.layer3 = nn.Linear(number_of_neurons,10)

        # nn.LeakyReLU()
        # nn.PReLU()
        self.activation_function = activation_function()
        self.softmax_function = nn.Softmax(dim=1)

    def forward(self,x):
        # In forward propogation since there are two options in the hidden layer,
        # I divided into to two if part.
        if self.number_of_hidden_layers == 1:
            hidden_layer_output = self.activation_function(self.layer1(x))
            output_layer = self.layer2(hidden_layer_output)
        if self.number_of_hidden_layers == 2:
            hidden_layer_output = self.activation_function(self.layer1(x))
            hidden_layer_output_2 = self.activation_function(self.layer2(hidden_layer_output))
            output_layer = self.layer3(hidden_layer_output_2)
        return output_layer

# we load all the datasets of Part 3
x_train, y_train = pickle.load(open("data/mnist_train.data", "rb"))
x_validation, y_validation = pickle.load(open("data/mnist_validation.data", "rb"))
x_test, y_test = pickle.load(open("data/mnist_test.data", "rb"))

x_train = x_train/255.0
x_train = x_train.astype(np.float32)

x_test = x_test / 255.0
x_test = x_test.astype(np.float32)

x_validation = x_validation/255.0
x_validation = x_validation.astype(np.float32)

# and converting them into Pytorch tensors in order to be able to work with Pytorch
x_train = torch.from_numpy(x_train)
y_train = torch.from_numpy(y_train).to(torch.long)

x_validation = torch.from_numpy(x_validation)
y_validation = torch.from_numpy(y_validation).to(torch.long)

x_test = torch.from_numpy(x_test)
y_test = torch.from_numpy(y_test).to(torch.long)

# In this part I created all the different model and then I created all different optimizer.
# Since I want to analyze all hyperparameter effect one by one, I changed the hyperparameter values one by one
# then I combined them.
model1 = MLPModel(1,8,0.001,nn.LeakyReLU,250)
optimizer1 = torch.optim.Adam(model1.parameters(),model1.learning_rate)
model2 = MLPModel(1,16,0.001,nn.LeakyReLU,250)
optimizer2 = torch.optim.Adam(model2.parameters(),model2.learning_rate)
model3 = MLPModel(1,8,0.002,nn.LeakyReLU,250)
optimizer3 = torch.optim.Adam(model3.parameters(),model3.learning_rate)
model4 = MLPModel(1,8,0.001,nn.PReLU,250)
optimizer4 = torch.optim.Adam(model4.parameters(),model4.learning_rate)
model5 = MLPModel(1,8,0.001,nn.LeakyReLU,500)
optimizer5 = torch.optim.Adam(model5.parameters(),model5.learning_rate)
model6 = MLPModel(2,8,0.001,nn.LeakyReLU,250)
optimizer6 = torch.optim.Adam(model6.parameters(),model6.learning_rate)
model7 = MLPModel(2,16,0.001,nn.LeakyReLU,250)
optimizer7 = torch.optim.Adam(model7.parameters(),model7.learning_rate)
model8 = MLPModel(2,16,0.002,nn.LeakyReLU,250)
optimizer8 = torch.optim.Adam(model8.parameters(),model8.learning_rate)
model9 = MLPModel(2,16,0.002,nn.PReLU,500)
optimizer9 = torch.optim.Adam(model9.parameters(),model9.learning_rate)
model10 = MLPModel(2,16,0.01,nn.PReLU,500)
optimizer10 = torch.optim.Adam(model10.parameters(),model10.learning_rate)

# In this following code part, I added the model and optimizer to the list.
keep_all_model_and_optimizer = []
keep_all_model_and_optimizer.append((model1,optimizer1))
keep_all_model_and_optimizer.append((model2,optimizer2))
keep_all_model_and_optimizer.append((model3,optimizer3))
keep_all_model_and_optimizer.append((model4,optimizer4))
keep_all_model_and_optimizer.append((model5,optimizer5))
keep_all_model_and_optimizer.append((model6,optimizer6))
keep_all_model_and_optimizer.append((model7,optimizer7))
keep_all_model_and_optimizer.append((model8,optimizer8))
keep_all_model_and_optimizer.append((model9,optimizer9))
keep_all_model_and_optimizer.append((model10,optimizer10))

#keep_all_mean_accuracy = []
loss_function = torch.nn.CrossEntropyLoss()
mean_iterations = []

# Based on the recitation slides, since I have a 10 model the first loop range in the(0,100)
for i in range(0,10):
    # According to the assignment.pdf, we have to run each model 10 times, so this for loop range in between (1,11)
    for j in range(1,11):
        list_validation_accuracy = []
        for iteration in range(1, keep_all_model_and_optimizer[i][0].epoch + 1):
            # I did the loss_value, prediction calculations and backpropagation in this part.
            keep_all_model_and_optimizer[i][1].zero_grad()
            predictions = keep_all_model_and_optimizer[i][0](x_train)
            loss_value = loss_function(predictions, y_train)
            loss_value.backward()
            keep_all_model_and_optimizer[i][1].step()

            with torch.no_grad():
                #I calculate the validation prediction, loss and accuracy in the following code piece.
                validation_predictions = keep_all_model_and_optimizer[i][0](x_validation)
                validation_loss = loss_function(validation_predictions, y_validation)
                validation_prediction_arr = torch.argmax(validation_predictions, dim=1)
                validation_accuracy = validation_prediction_arr[validation_prediction_arr == y_validation].size()[0] / \
                                      y_validation.size()[0] * 100
                list_validation_accuracy.append(validation_accuracy)
                #print("iteration: %d - Validation Loss: %f - Validation accuracy %f" % (iteration, validation_loss, validation_accuracy))
        mean_iterations.append(sum(list_validation_accuracy) / len(list_validation_accuracy))

each_model_accuracy_mean = []
count = 0
# In the following for loop, I calculate the overall mean of the each model
for i in range(1,101):
    count += mean_iterations[i-1]
    if i % 10 == 0:
        each_model_accuracy_mean.append(count/10)
        count = 0

each_model_standard_deviation = []
tmp_list = []
# In the following code piece, I calculate the each standard deviation of the each model
for i in range(1,101):
    tmp_list.append(mean_iterations[i-1])
    if i % 10 == 0:
        each_model_standard_deviation.append(np.std(tmp_list))
        tmp_list = []
# I calculate the all confidence interval of the all model.
each_model_confidence_interval = []
for i in range(0,10):
    conf_left = each_model_accuracy_mean[i] - 1.96 * each_model_standard_deviation[i] / 3.16227
    conf_right = each_model_accuracy_mean[i] + 1.96 * each_model_standard_deviation[i] / 3.16227
    each_model_confidence_interval.append((conf_left,conf_right))

max_index = 0
max_val = each_model_accuracy_mean[0]
# In the following for loop I calculate the maximum value and maximum index.
for i in range(1,10):
    if each_model_accuracy_mean[i] > max_val:
        max_val = each_model_accuracy_mean[i]
        max_index = i

# In order the create last dataset, I join the validation and train dataset.
x_new_dataset = torch.cat((x_validation,x_train),dim=0)
y_new_dataset = torch.cat((y_validation,y_train),dim=0)

# I do the same calculations above, actually the code block is the repetaiton of the above code block,just
# some parameters is changed.
test_means = []
for j in range(1, 11):
    list_test_accuracy = []
    for iteration in range(1, keep_all_model_and_optimizer[max_index][0].epoch + 1):
        keep_all_model_and_optimizer[max_index][1].zero_grad()
        predictions = keep_all_model_and_optimizer[max_index][0](x_new_dataset)
        loss_value = loss_function(predictions, y_new_dataset)
        loss_value.backward()
        keep_all_model_and_optimizer[max_index][1].step()

        with torch.no_grad():
            test_predictions = keep_all_model_and_optimizer[max_index][0](x_test)
            test_loss = loss_function(test_predictions, y_test)
            test_prediction_arr = torch.argmax(test_predictions, dim=1)
            test_accuracy = test_prediction_arr[test_prediction_arr == y_test].size()[0] / \
                                  y_test.size()[0] * 100
            list_test_accuracy.append(test_accuracy)
            #print("iteration: %d - Validation Loss: %f - Validation accuracy %f" % (iteration, test_loss, test_accuracy))
    test_means.append(sum(list_test_accuracy) / len(list_test_accuracy))

# calculate standard deviation for the last train
last_mean = 0
# I calculated the last train mean and also the standard deviation, confidence interval
for i in range(1,11):
    last_mean += test_means[i-1]
    if i % 10 == 0:
        last_mean = last_mean/10
last_standard_dev = np.std(test_means)
last_conf_left = last_mean - 1.96 * last_standard_dev / 3.16227
last_conf_right = last_mean + 1.96 * last_standard_dev / 3.16227

# In the following code session, I printed the all the accuracy_mean, standard deviation and the confidence interval
# in order to use the part3 report
for i in range(1,11):
    print("Model: %d - Mean Value: %f " % (i, each_model_accuracy_mean[i-1]))
for i in range(1,11):
    print("Model: %d - Standard Deviation: %f " % (i, each_model_standard_deviation[i-1]))
for i in range(1,11):
    print("Model: %d - confidence interval left: %f - confidence interval left: %f " % (i, each_model_confidence_interval[i - 1][0],each_model_confidence_interval[i - 1][1]))

# I also print the maximum mean, maximum value, and the last train mean, standard deviation, and the confidence interval
print("Max mean index",max_index+1)
print("Max mean value",max_val)

print("Last train mean: ",last_mean)
print("Last train standard deviation", last_standard_dev)
print("Last conf_left: ",last_conf_left)
print("Last conf_right: ",last_conf_right)


import os
import numpy as np
from matplotlib import pyplot as plt
import cv2
img_array = []
path = '/home/ash/labelme/IIIT_Labels/seq_5/SegmentationClassVisualization/'
files = sorted(os.listdir(path))[60:240]
for file in files:
    img = cv2.imread(os.path.join(path,file))
    img_array.append(img)
    size = (img.shape[1],img.shape[0])

fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('banner_vid.mp4',fourcc,20.0,size)
for i in range(len(img_array)):
    out.write(img_array[i])
out.release()


# This script takes a file containing ADCG chunks and decompresses them.
# Pillow is required as a dependency.
#
# The decompressed ADCG chunks are output in the working directory with the extension .adcg.
# The decompressed image data is then weaved into a complete image and saved as PNG.
# In files that contain them, ADCG headers are preceded by an AGR1 or AGR2 signature,
# which is followed by 00 00 00 00.
# Some values in the ADCG header are currently unknown.

import io
import mmap
import os
import struct
import subprocess
import sys
from collections import namedtuple
from PIL import Image
from utils import prs

path = os.path.realpath(os.path.dirname(sys.argv[0]))

# Set these to the path and arguments of a utility that accepts a PVR file and output a PNG file.
# It is recommended that the arguments include a switch that suppresses console output, if available.
pvr2png_path = os.path.join(path,os.path.normpath(r".\lib\pvr2png.exe"))
pvr2png_args = ["-q"]

def weave_adcg(input_data,address):
    """Extracts the PVR subtextures from an uncompressed ADCG chunk,
    and attempts to assemble it into a full image based on the properties
    in the ADCG header."""

    ADCGSubTexture = namedtuple("ADCGSubTexture","id offset x y value1")

    with io.BytesIO(input_data) as stream:
        signature = stream.read(4)
        adcg_size = struct.unpack("<I",stream.read(4))[0]
        value1 = stream.read(4) # 00 00 00, followed by a single byte. Possible signed 2-byte value?
        textures_num = struct.unpack("<I",stream.read(4))[0]

        texture_width = struct.unpack("<H",stream.read(2))[0]
        texture_height = struct.unpack("<H",stream.read(2))[0]
        value2 = stream.read(4) # 18 00 00 00. Offset - 8?

        pvr_format = stream.read(4)[0:2]

        total_width = struct.unpack("<H",stream.read(2))[0]
        total_height = struct.unpack("<H",stream.read(2))[0]

        # Initialize output image.
        output_image = Image.new("RGBA",(total_width,total_height))

        textures = []

        for _ in range(textures_num):
            textures.append(ADCGSubTexture(struct.unpack("<I",stream.read(4))[0],
                                           struct.unpack("<I",stream.read(4))[0],
                                           struct.unpack("<H",stream.read(2))[0],
                                           struct.unpack("<H",stream.read(2))[0],
                                           stream.read(4)))

        # Create PVR textures.
        for i,data in enumerate(textures):
            stream.seek(data.offset + 32 + (16 * i))

            try:
                # Texture size is calculated from offset of next texture, plus 16.
                texture_size = textures[i+1].offset - data.offset + 16
                texture_data = stream.read(texture_size)
            except IndexError:
                # For last texture, read to end of file.
                texture_data = stream.read(adcg_size - data.offset + 16)

            chunk_size = struct.pack("<I",len(texture_data) + 8)

            output = b'PVRT' + chunk_size + pvr_format + b'\x00\x00' + struct.pack("<H",texture_width) + struct.pack("<H",texture_height) + texture_data

            with open("~temp.pvr","wb") as output_file:
                output_file.write(output)

            # Convert PVR texture to PNG.
            pvr_convert = subprocess.run([pvr2png_path,"~temp.pvr","~temp.png"] + pvr2png_args,shell=True)
            pvr_convert.check_returncode()

            # Load converted texture into an Image object.
            if os.path.isfile("~temp.png"):
                with Image.open("~temp.png") as png:
                    output_image.paste(png,(data.x,data.y))
            else:
                print(f"Error processing subtexture in ADCG chunk at {address}. Check output.")
                continue

        if os.path.isfile("~temp.pvr"):
            os.remove("~temp.pvr")
        if os.path.isfile("~temp.png"):
            os.remove("~temp.png")

        return output_image

def extract_adcg(input_file,offset=0,end=-1):
    """From input_file, searches for ADCG chunks and decompresses them.
    The original uncompressed ADCG data is saved to file, as its header is
    required to reconstruct the file after editing the image.
    Each chunk is then assembled into a complete image file and saved as PNG.

    If the offset argument is set, start searching that many bytes into the file.
    If the end argument is set, stop searching after this many bytes."""

    adcg_index = 0
    files_written = 0

    with open(input_file,"rb") as f:

        with mmap.mmap(f.fileno(),0,access=mmap.ACCESS_READ) as mm:

            if end < 0:
                end = len(mm)

            while True:
                # Decompress a single ADCG chunk.
                adcg_pos = mm.find(b'ADCG',mm.tell())

                if adcg_pos > end:
                    return files_written

                if adcg_pos != -1:
                    mm.seek(adcg_pos)

                    # Skip offset bytes, but attempt to keep index number accurate.
                    if mm.tell() >= offset:
                        abs_offset = hex(mm.tell())
                        adcg_prs_data = bytearray()

                        while True:
                            buffer = mm.read(4)
                            adcg_prs_data += buffer
                            if buffer == b'EOFC':
                                adcg_prs_data += mm.read(4)
                                break

                        try:
                            adcg_uncompressed = bytes(prs.decompress(adcg_prs_data))
                        except Exception as e:
                            print(e)
                            print(f"Error processing ADCG chunk at {abs_offset}. Continuing with next chunk.")
                            continue

                        # Save uncompressed ADCG data and PNG to file.
                        filename = input_file + "_" + str(adcg_index).zfill(4) + "_" + abs_offset

                        with open(filename + ".adcg","wb") as raw_file:
                            raw_file.write(adcg_uncompressed)

                        output_image = weave_adcg(adcg_uncompressed,abs_offset)

                        with open(filename + ".png","wb") as output_file:
                            output_image.save(output_file)
                            files_written += 1
                            print(f"{output_file.name}: Dimensions: {output_image.size}.")

                    else:
                        print(f"Skipping ADCG chunk {str(adcg_index).zfill(4)} at {hex(mm.tell())}.")
                        mm.seek(4,1)

                    adcg_index += 1

                else:
                    return files_written

def main():

    if len(sys.argv) > 2:
        if len(sys.argv) >= 4:
            files_written = extract_adcg(sys.argv[1],int(sys.argv[2],(16 if sys.argv[2].startswith("0x") else 10)),int(sys.argv[3]))
        elif len(sys.argv) == 3:
            files_written = extract_adcg(sys.argv[1],int(sys.argv[2],(16 if sys.argv[2].startswith("0x") else 10)))
        else:
            files_written = extract_adcg(sys.argv[1])
    elif len(sys.argv) == 2:
        files_written = extract_adcg(sys.argv[1])
    else:
        print("Specify input file containing ADCG data.\nOptional arguments: number of bytes to skip; number of bytes to search. Hex offsets starting with 0x allowed.")
        return

    print(f"\nWrote {files_written} ADCG + PNG file pairs.")

if __name__ == "__main__":
    main()


from django.shortcuts import render, redirect
from courses.models import Directions

def index(request):
    template = 'landing/app.html'

    directions = Directions.objects.all()
    if request.method == 'POST':
        course_name = request.POST.get('course_name')
        select_course = request.POST.get('select_course')
        if course_name and select_course:
            # Оба значения переданы, перенаправляем на другой метод с двумя параметрами
            return redirect('courses:courses-search', course_name=course_name, select_course=select_course)
        elif course_name:
            # Передано только значение course_name
            return redirect('courses:courses-search', course_name=course_name, select_course=None)
        elif select_course:
            # Передано только значение select_course
            return redirect('courses:courses-search', course_name=None, select_course=select_course)
        else:
            # Не передано ни одно значение
            return redirect('courses:courses-search', course_name=None, select_course=None)
    context = {
    'request': request,
    'directions': directions
    }
    return render(request, template, context)