from PySide6.QtCore import Qt, QItemSelectionModel
from PySide6.QtWidgets import (
    QCheckBox, QComboBox, QHBoxLayout, QHeaderView, QSizePolicy,
    QTableWidgetItem, QWidget
)

from hexrdgui.constants import OverlayType
from hexrdgui.hexrd_config import HexrdConfig
from hexrdgui.overlay_editor import OverlayEditor
from hexrdgui.overlay_style_picker import OverlayStylePicker
from hexrdgui.ui_loader import UiLoader
from hexrdgui.utils import block_signals
from hexrdgui.utils.dialog import add_help_url

COLUMNS = {
    'name': 0,
    'material': 1,
    'type': 2,
    'visible': 3,
}

class OverlayManager:

    def __init__(self, parent=None):
        loader = UiLoader()
        self.ui = loader.load_file('overlay_manager.ui', parent)

        self.overlay_editor = OverlayEditor(self.ui.overlay_manager_widget)
        self.ui.overlay_editor_layout.addWidget(self.overlay_editor.ui)
        flags = self.ui.windowFlags()
        self.ui.setWindowFlags(flags | Qt.Tool)

        add_help_url(self.ui.button_box, 'configuration/overlays/')

        self.material_combos = []
        self.type_combos = []
        self.visibility_boxes = []

        self.setup_connections()

    def setup_connections(self):
        self.ui.table.selectionModel().selectionChanged.connect(
            self.selection_changed)
        self.ui.table.itemChanged.connect(self.table_item_changed)
        self.ui.add_button.pressed.connect(self.add)
        self.ui.remove_button.pressed.connect(self.remove)
        self.ui.edit_style_button.pressed.connect(self.edit_style)
        HexrdConfig().update_overlay_editor.connect(self.update_overlay_editor)
        HexrdConfig().materials_added.connect(self.update_table)
        HexrdConfig().material_renamed.connect(self.on_material_renamed)
        HexrdConfig().materials_removed.connect(self.update_table)

        HexrdConfig().state_loaded.connect(self.update_table)

    def show(self):
        self.update_table()
        self.ui.show()

    @staticmethod
    def format_type(type):
        types = {
            OverlayType.powder: 'Powder',
            OverlayType.laue: 'Laue',
            OverlayType.rotation_series: 'Rotation Series',
        }

        if type not in types:
            raise Exception(f'Unknown type: {type}')

        return types[type]

    def create_materials_combo(self, v):
        materials = list(HexrdConfig().materials.keys())

        if v not in materials:
            raise Exception(f'Unknown material: {v}')

        cb = QComboBox(self.ui.table)
        size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        cb.setSizePolicy(size_policy)
        for mat in materials:
            cb.addItem(mat, mat)

        cb.setCurrentIndex(materials.index(v))
        cb.currentIndexChanged.connect(self.update_config_materials)
        self.material_combos.append(cb)
        return self.create_table_widget(cb)

    def on_material_renamed(self, old_name, new_name):
        self.update_table()

    def create_type_combo(self, v):
        types = list(OverlayType)
        if v not in types:
            raise Exception(f'Unknown type: {v}')

        cb = QComboBox(self.ui.table)
        size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        cb.setSizePolicy(size_policy)
        for type in types:
            cb.addItem(self.format_type(type), type.value)

        cb.setCurrentIndex(types.index(v))
        cb.currentIndexChanged.connect(self.update_config_types)
        self.type_combos.append(cb)
        return self.create_table_widget(cb)

    def create_visibility_checkbox(self, v):
        cb = QCheckBox(self.ui.table)
        cb.setChecked(v)
        cb.toggled.connect(self.update_config_visibilities)
        self.visibility_boxes.append(cb)
        return self.create_table_widget(cb)

    def create_table_widget(self, w):
        # These are required to center the widget...
        tw = QWidget(self.ui.table)
        layout = QHBoxLayout(tw)
        layout.addWidget(w)
        layout.setAlignment(Qt.AlignCenter)
        layout.setContentsMargins(0, 0, 0, 0)
        return tw

    def clear_table(self):
        self.material_combos.clear()
        self.type_combos.clear()
        self.visibility_boxes.clear()
        self.ui.table.clearContents()

    def update_table(self):
        block_list = [
            self.ui.table,
            self.ui.table.selectionModel()
        ]

        with block_signals(*block_list):
            prev_selected = self.selected_row

            overlays = HexrdConfig().overlays
            self.clear_table()
            self.ui.table.setRowCount(len(overlays))
            for i, overlay in enumerate(overlays):
                w = QTableWidgetItem(overlay.name)
                self.ui.table.setItem(i, COLUMNS['name'], w)

                w = self.create_materials_combo(overlay.material_name)
                self.ui.table.setCellWidget(i, COLUMNS['material'], w)

                w = self.create_type_combo(overlay.type)
                self.ui.table.setCellWidget(i, COLUMNS['type'], w)

                w = self.create_visibility_checkbox(overlay.visible)
                self.ui.table.setCellWidget(i, COLUMNS['visible'], w)

            if prev_selected is not None:
                select_row = (prev_selected if prev_selected < len(overlays)
                              else len(overlays) - 1)
                self.select_row(select_row)

            self.ui.table.resizeColumnsToContents()

            # The last section isn't always stretching automatically, even
            # though we have setStretchLastSection(True) set.
            # Force it to stretch manually.
            last_column = max(v for v in COLUMNS.values())
            self.ui.table.horizontalHeader().setSectionResizeMode(
                last_column, QHeaderView.Stretch)

            # Just in case the selection actually changed...
            self.selection_changed()

    def select_row(self, i):
        if i is None or i >= self.ui.table.rowCount():
            # Out of range. Don't do anything.
            return

        # Select the row
        selection_model = self.ui.table.selectionModel()
        selection_model.clearSelection()

        model_index = selection_model.model().index(i, 0)
        command = QItemSelectionModel.Select | QItemSelectionModel.Rows
        selection_model.select(model_index, command)

    @property
    def selected_row(self):
        selected = self.ui.table.selectionModel().selectedRows()
        return selected[0].row() if selected else None

    def selection_changed(self):
        self.update_enable_states()
        self.update_overlay_editor()

    def update_enable_states(self):
        row_selected = self.selected_row is not None
        self.ui.remove_button.setEnabled(row_selected)
        self.ui.edit_style_button.setEnabled(row_selected)

    def update_overlay_editor(self):
        self.overlay_editor.overlay = self.active_overlay

    def update_config_materials(self):
        any_changed = False
        for i in range(self.ui.table.rowCount()):
            w = self.material_combos[i]
            overlay = HexrdConfig().overlays[i]
            if overlay.material_name != w.currentData():
                overlay.material_name = w.currentData()
                any_changed = True

        if any_changed:
            # In case the material was renamed
            self.update_table()

            # In case the active widget depends on material settings
            self.overlay_editor.update_active_widget_gui()

            HexrdConfig().update_visible_material_energies()
            HexrdConfig().overlay_config_changed.emit()

    def update_config_types(self):
        for i in range(self.ui.table.rowCount()):
            w = self.type_combos[i]
            # This won't do anything if the type already matches
            HexrdConfig().change_overlay_type(i, OverlayType(w.currentData()))

        HexrdConfig().overlay_config_changed.emit()
        self.update_table()
        self.update_overlay_editor()

    def update_config_visibilities(self):
        for i in range(self.ui.table.rowCount()):
            w = self.visibility_boxes[i]
            HexrdConfig().overlays[i].visible = w.isChecked()

        HexrdConfig().update_visible_material_energies()
        HexrdConfig().overlay_config_changed.emit()

    @property
    def active_material_name(self):
        return HexrdConfig().active_material_name

    @property
    def active_overlay(self):
        overlays = HexrdConfig().overlays
        i = self.selected_row
        if i is None or i >= len(overlays):
            return None

        return overlays[i]

    def update_refinement_options(self):
        self.overlay_editor.update_refinement_options()

    def table_item_changed(self, item):
        col = item.column()
        if col == COLUMNS['name']:
            return self.overlay_name_edited(item)
        else:
            raise Exception(f'Item editing not implemented for column: {col}')

    def overlay_name_edited(self, item):
        row = item.row()
        new_name = item.text()
        modified_overlay = HexrdConfig().overlays[row]
        old_name = modified_overlay.name

        # If the name matches any other overlay names, revert back so that
        # we can keep unique names.
        for overlay in HexrdConfig().overlays:
            if new_name == overlay.name:
                # This name already exists. Revert changes.
                item.setText(old_name)
                return

        modified_overlay.name = new_name
        HexrdConfig().overlay_renamed.emit(old_name, new_name)

    def add(self):
        HexrdConfig().append_overlay(self.active_material_name,
                                     OverlayType.powder)
        self.update_table()
        self.select_row(len(HexrdConfig().overlays) - 1)

    def remove(self):
        HexrdConfig().overlays.pop(self.selected_row)
        HexrdConfig().overlay_list_modified.emit()
        HexrdConfig().overlay_config_changed.emit()
        self.update_table()

    def edit_style(self):
        self._style_picker = OverlayStylePicker(self.active_overlay, self.ui)
        self._style_picker.exec()


# Imports
import sys
if sys.version_info.major < 3 or sys.version_info.minor < 4:
    raise RuntimeError('At least Python 3.4 is required')

import keyboard
import pygame
import requests

HOST = '10.148.131.75'
PORT = '8000'

# BASE_URL is variant use to save the format of host and port
BASE_URL = 'http://' + HOST + ':'+ PORT + '/'

def __request__(url, times=10):
    for x in range(times):
        try:
            requests.get(url)
            return 0
        except :
            print("Connection error, try again")
    print("Abort")
    return -1

def run_action(cmd):
    """Ask server to do sth, use in running mode

    Post requests to server, server will do what client want to do according to the url.
    This function for running mode

    Args:
        # ============== Back wheels =============
        'bwready' | 'forward' | 'backward' | 'stop'

        # ============== Front wheels =============
        'fwready' | 'fwleft' | 'fwright' |  'fwstraight'

        # ================ Camera =================
        'camready' | 'camleft' | 'camright' | 'camup' | 'camdown'
    """
    # set the url include action information
    url = BASE_URL + 'run/?action=' + cmd
    print('url: %s'% url)
    # post request with url
    __request__(url)

def run_speed(speed):
    """Ask server to set speed, use in running mode

    Post requests to server, server will set speed according to the url.
    This function for running mode.

    Args:
        '0'~'100'
    """
    # Set set-speed url
    url = BASE_URL + 'run/?speed=' + speed
    print('url: %s'% url)
    # Set speed
    __request__(url)

def connection_ok():
    """Check whetcher connection is ok

    Post a request to server, if connection ok, server will return http response 'ok'

    Args:
        none

    Returns:
        if connection ok, return True
        if connection not ok, return False

    Raises:
        none
    """
    cmd = 'connection_test'
    url = BASE_URL + cmd
    print('url: %s'% url)
    # if server find there is 'connection_test' in request url, server will response 'Ok'
    try:
        r=requests.get(url)
        if r.text == 'OK':
            return True
    except:
        return False

class Steering():
    """docstring for Steering"""
    def __init__(self):
        self.clock = pygame.time.Clock()

        self.backward = False # start with moving forward
        self.direction = 0 # 0 is straight, 1 is left, 2 is right
        self.speed = 60 # initial speed, speed is 0-100
        self.camera_up_angle = 0
        self.camera_left_angle = 0

    def drive(self):
        while True:
            # terminate program press 'q'
            if keyboard.is_pressed('q'):
                print('Terminating program')
                break
            # turn left
            if keyboard.is_pressed('a'):
                if self.direction != 1:
                    self.direction = 1
                    print('left')
                    run_action('fwleft')
            # turn right
            elif keyboard.is_pressed('d'):
                if self.direction != 2:
                    self.direction = 2
                    print('right')
                    run_action('fwright')
            # go straight
            else:
                if self.direction != 0:
                    self.direction = 0
                    print('straight')
                    run_action('fwstraight')
            # move
            if keyboard.is_pressed('w'):
                if not self.backward:
                    print('forward')
                    run_action('forward')
                else:
                    print('backward')
                    run_action('backward')
            # stop
            elif keyboard.is_pressed('s'):
                print('stop')
                run_action('stop')
            # shift gear between forward and backward
            if keyboard.is_pressed('b'):
                if self.backward:
                    print('change mode from backward to forward')
                else:
                    print('change mode from forward to backward')
                self.backward = not self.backward
            # use "i j k l" to control camera direction
            if keyboard.is_pressed('i'):
                if self.camera_up_angle < 60:
                    self.camera_up_angle += 20
                    run_action('camup')
            elif keyboard.is_pressed('k'):
                if self.camera_up_angle > -40:
                    self.camera_up_angle -= 20
                    run_action('camdown')
            elif keyboard.is_pressed('j'):
                if self.camera_left_angle < 3:
                    self.camera_left_angle += 1
                    run_action('camleft')
            elif keyboard.is_pressed('l'):
                if self.camera_left_angle > -3:
                    self.camera_left_angle -= 1
                    run_action('camright')
            # accelerate
            if keyboard.is_pressed('n'):
                if self.speed < 100:
                    self.speed += 20
                    run_speed(str(self.speed))
            # deaccelerate
            elif keyboard.is_pressed('m'):
                if self.speed > 20:
                    self.speed -= 20
                    run_speed(str(self.speed))
            # check keyboard input 10 times every second
            self.clock.tick(10)

if __name__ == '__main__':
    # check connection
    print('connection:', connection_ok())
    wheel = Steering()
    wheel.drive()


import weakref

class CarModel:
    _models = weakref.WeakValueDictionary()

    def __new__(cls, model_name, *args, **kwargs):
        model = cls._models.get(model_name)
        if not model:
            model = super().__new__(cls)
            cls._models[model_name] = model

        return model

    def __init__(self, model_name, air=False, tilt=False,
            cruise_control=False, power_locks=False,
            alloy_wheels=False, usb_charger=False):
        if not hasattr(self, "initialized"):
            self.model_name = model_name
            self.air = air
            self.tilt = tilt
            self.cruise_control = cruise_control
            self.power_locks = power_locks
            self.alloy_wheels = alloy_wheels
            self.usb_charger = usb_charger
            self.initialized=True


"""
Tic Tac Toe Player
"""

import math
import copy

X = "X"
O = "O"
EMPTY = None

def initial_state():
    """
    Returns starting state of the board.
    """
    return [[EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY],
            [EMPTY, EMPTY, EMPTY]]

def player(board):
    count_X = 0
    count_O = 0

    for row in range(len(board)):
        for col in range(len(board[row])):
            if board [row] [col] == X:
                count_X += 1
            if board [row][col] == O:
                count_O += 1

    if count_X > count_O:
        return O
    else:
        return X

def actions(board):
    available_actions = set()

    for i in range(len(board)):
        for j in range(len(board[i])):
            if board[i][j] == EMPTY:
                available_actions.add((i, j))

    return available_actions

def result(board, action):
    """
    Returns the board that results from making move (i, j) on the board.
    """
    if action not in actions(board):
        raise Exception('Invalid Action')

    i, j = action
    board_copy = copy.deepcopy(board)

    board_copy[i][j] = player(board)

    return board_copy

def checkRow(board, player):
    for row in range(len(board)):
        if board [row] [0] == player and board [row] [1] == player and board [row] [2] == player:
            return True
    return False

def checkCol(board, player):
    for col in range(len(board)):
       if board [0] [col] == player and board [1] [col] == player and board [2] [col] == player:
            return True
    return False

def checkFirstDiag(board, player):
    for row in range(len(board)):
        for col in range(len(board[row])):
            if board[0][0] == player and board[1][1] == player and board[2][2] == player:
                return True
    return False

def checkSecondDiag(board, player):
    for row in range(len(board)):
        for col in range(len(board[row])):
            if board[0][2] == player and board[1][1] == player and board[2][0] == player:
                return True
    return False

def winner(board):
    """
    Returns the winner of the game, if there is one.
    """
    if checkRow(board, X) or checkCol(board, X) or checkFirstDiag(board, X) or checkSecondDiag(board, X):
        return X
    elif checkRow(board, O) or checkCol(board, O) or checkFirstDiag(board, O) or checkSecondDiag(board, O):
        return O
    else:
        return None

def terminal(board):
    """
    Returns True if game is over, False otherwise.
    """
    if winner(board) == X:
        return True
    if winner(board) == O:
        return True
    for row in range(len(board)):
        for col in range(len(board[row])):
            if board[row][col] == EMPTY:
                return False
    return True

def utility(board):
    """
    Returns 1 if X has won the game, -1 if O has won, 0 otherwise.
    """

    if winner(board) == X:
        return 1
    elif winner(board) == O:
        return -1
    else:
        return 0

def max_val(board):
    v = -math.inf
    if terminal(board):
        return utility(board)
    for action in actions(board):
        v = max(v, min_val(result(board, action)))
    return v

def min_val(board):
    v = math.inf
    if terminal(board):
        return utility(board)
    for action in actions(board):
        v = min(v, max_val(result(board, action)))
    return v

def minimax(board):
    """
    Returns the optimal action for the current player on the board.
    """
    if terminal(board):
        return None
    elif player(board) == X:
        plays = []
        for action in actions(board):
            plays.append([min_val(result(board, action)), action])
        return sorted(plays, key=lambda x: x[0], reverse=True)[0][1]
    elif player(board) == O:
        plays = []
        for action in actions(board):
            plays.append([max_val(result(board, action)), action])
        return sorted(plays, key=lambda x: x[0])[0][1]


########################################################################
#
# File:   cnn_mine.py
# Author: Matt Zucker
# Date:   March 2020
#
# Written for ENGR 27 - Computer Vision
#
########################################################################
#
# attempt to improve on keras tutorial with deeper network that has
# 80% fewer parameters

import keras
import numpy as np

import mnist_preprocess

BATCH_SIZE = 128
NUM_HIDDEN = 300
NUM_CLASSES = 10
EPOCHS = 12

def main():

    (x_train, y_train), (x_test, y_test) = mnist_preprocess.load_datasets(
        conv=True, activation='softmax')

    input_shape = x_train.shape[1:]
    print('input_shape =', input_shape)

    model = keras.models.Sequential()

    shapes = [(16, 32), (64,)]

    for shape_tuple in shapes:

        for channels in shape_tuple:

            # kernel shape is (32, 3, 3, 1)
            model.add(keras.layers.Conv2D(channels, kernel_size=(3, 3),
                                          activation='relu',
                                          input_shape=input_shape))

            input_shape = model.layers[-1].output_shape[1:]
            print('after conv2d now input shape is', input_shape)

        # apply a maximum operation over 2x2 neighborhoods in the image
        model.add(keras.layers.MaxPooling2D(pool_size=(2, 2)))

        model.add(keras.layers.Dropout(0.15))

        input_shape = model.layers[-1].output_shape[1:]
        print('after max pooling now input shape is', input_shape)

    model.add(keras.layers.Flatten())

    model.add(keras.layers.Dense(128, activation='relu'))

    model.add(keras.layers.Dropout(0.5))

    model.add(keras.layers.Dense(NUM_CLASSES, activation='softmax'))

    model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer=keras.optimizers.Adadelta(),
                  metrics=['accuracy'])

    model.summary()

    model.fit(x_train, y_train,
              batch_size=BATCH_SIZE,
              epochs=EPOCHS,
              verbose=1,
              validation_data=(x_test, y_test))

    loss, accuracy = model.evaluate(x_train, y_train, verbose=1)
    print('Train loss={:7.5f}, accuracy={:7.5f}'.format(loss, accuracy))

    loss, accuracy = model.evaluate(x_test, y_test, verbose=1)
    print('Test  loss={:7.5f}, accuracy={:7.5f}'.format(loss, accuracy))

    filename = 'models/cnn_mz.h5'

    model.save(filename)
    print('wrote', filename)

if __name__ == '__main__':
    main()


from tkinter import *

from tkinter import messagebox

pencere = Tk()

pencere.title("title")
pencere.geometry("600x300")

uygulama = Frame(pencere)
uygulama.grid()

def dialog():
    var = messagebox.showwarning("Uyarı" , "mesaj")

button1 = Button(uygulama, text = " Uyarı Ver " , width=20, command=dialog)
button1.grid(padx=110, pady=80)

pencere.mainloop()


#!/usr/bin/env python3

from selectolax.parser import HTMLParser
import locale
import requests
import re

locale.setlocale(locale.LC_ALL, 'en_US.UTF8')
html = requests.get("https://en.wikipedia.org/wiki/List_of_largest_cities").text
html_data = HTMLParser(html)
objs = html_data.css("table.wikitable")
table = objs[0]
rows = table.css("tr")

for row in rows:
    columns = row.css("td")
    if len(columns) == 10:
        city = re.findall('(.*?)(?:\[|$)', columns[0].text().strip())[0]
        state = re.findall('(.*?)(?:\[|$)', columns[1].text().strip())[0]
        definition = re.findall('(.*?)(?:\[|$)', columns[3].text().rstrip())[0]

        # City Stats
        city_population = re.findall('(.*?)(?:\[|$)', columns[4].text())[0]
        if city_population != "N/A":
            city_population = locale.atoi(city_population)
        city_area = re.findall('(.*?)(?:\[|$)', columns[5].text())[0]
        if city_area != "N/A":
            city_area = locale.atoi(city_area)

        # Metro Stats
        metro_population = re.findall('(.*?)(?:\[|$)', columns[4].text())[0]
        if metro_population != "N/A":
            metro_population = locale.atoi(metro_population)
        metro_area = re.findall('(.*?)(?:\[|$)', columns[5].text())[0]
        if metro_area != "N/A":
            metro_area = locale.atoi(metro_area)

        # Urban Stats
        urban_population = re.findall('(.*?)(?:\[|$)', columns[4].text())[0]
        if urban_population != "N/A":
            urban_population = locale.atoi(urban_population)
        urban_area = re.findall('(.*?)(?:\[|$)', columns[5].text())[0]
        if urban_area != "N/A":
            urban_area = locale.atoi(urban_area)

        print(city, state, definition, city_population, city_area, metro_population, metro_area, urban_population, urban_area)


items = [5, 9, 4, 3, 4, 9, 1, 5, 9]
some = []
for x in items:
    if x not in some:
        some.append(x)

print(some)

def func(items):
    seen = set()
    for item in items:
        if item not in seen:
            yield item
            seen.add(item)

if __name__ == '__main__':
    print(list(func([5, 9, 4, 3, 4, 9, 1, 5, 9])))


import torch.nn as nn
import torch.nn.functional as F
import torch
import numpy as np
from torch.nn import init
from torch.autograd import Function
#torch.manual_seed(42)
from models import transformer

class dummyhgru(Function):
    @staticmethod
    def forward(ctx, state_2nd_last, last_state, *args):
        ctx.save_for_backward(state_2nd_last, last_state)
        ctx.args = args
        return last_state

    @staticmethod
    def backward(ctx, grad):
        neumann_g = neumann_v = None
        neumann_g_prev = grad.clone()
        neumann_v_prev = grad.clone()

        state_2nd_last, last_state = ctx.saved_tensors

        args = ctx.args
        truncate_iter = args[-1]
        exp_name = args[-2]
        i = args[-3]
        epoch = args[-4]

        normsv = []
        normsg = []
        normg = torch.norm(neumann_g_prev)
        normsg.append(normg.data.item())
        normsv.append(normg.data.item())
        for ii in range(truncate_iter):
            neumann_v = torch.autograd.grad(last_state, state_2nd_last, grad_outputs=neumann_v_prev,
                                            retain_graph=True, allow_unused=True)
            normv = torch.norm(neumann_v[0])
            neumann_g = neumann_g_prev + neumann_v[0]
            normg = torch.norm(neumann_g)

            if normg > 1 or normv > normsv[-1] or normv < 1e-9:
                normsg.append(normg.data.item())
                normsv.append(normv.data.item())
                neumann_g = neumann_g_prev
                break

            neumann_v_prev = neumann_v
            neumann_g_prev = neumann_g

            normsv.append(normv.data.item())
            normsg.append(normg.data.item())

        return (None, neumann_g, None, None, None, None)

class hConvGRUCell(nn.Module):
    """
    Generate a convolutional GRU cell
    """

    def __init__(self, hidden_size, kernel_size, timesteps, batchnorm=True, grad_method='bptt', use_attention=False):
        super(hConvGRUCell, self).__init__()
        self.padding = kernel_size // 2
        self.hidden_size = hidden_size
        self.batchnorm = batchnorm
        self.timesteps = timesteps
        self.use_attention = use_attention

        if self.use_attention:
            # self.a_w_gate = nn.Conv2d(hidden_size, 1, kernel_size, padding=self.padding)
            # self.a_u_gate = nn.Conv2d(hidden_size, 1, kernel_size, padding=self.padding)
            self.a_w_gate = nn.Conv2d(hidden_size, hidden_size, 1, padding=1 // 2)
            self.a_u_gate = nn.Conv2d(hidden_size, hidden_size, 1, padding=1 // 2)
            init.orthogonal_(self.a_w_gate.weight)
            init.orthogonal_(self.a_u_gate.weight)
            init.constant_(self.a_w_gate.bias, 1.)  # In future try setting to -1 -- originally set to 1
            init.constant_(self.a_u_gate.bias, 1.)
            # init.uniform_(self.a_w_gate.bias.data, 1, self.timesteps - 1)
            # init.uniform_(self.a_u_gate.bias.data, 1, self.timesteps - 1)
            # self.a_w_gate.bias.data.log()
            # self.a_w_gate.bias.data.log()

        self.i_w_gate = nn.Conv2d(hidden_size, hidden_size, 1)
        self.i_u_gate = nn.Conv2d(hidden_size, hidden_size, 1)
        self.e_w_gate = nn.Conv2d(hidden_size, hidden_size, 1)
        self.e_u_gate = nn.Conv2d(hidden_size, hidden_size, 1)

        spatial_h_size = kernel_size
        self.h_padding = spatial_h_size // 2
        self.w_exc = nn.Parameter(torch.empty(hidden_size, hidden_size, spatial_h_size, spatial_h_size))
        self.w_inh = nn.Parameter(torch.empty(hidden_size, hidden_size, spatial_h_size, spatial_h_size))

        self.alpha = nn.Parameter(torch.empty((hidden_size, 1, 1)))
        self.gamma = nn.Parameter(torch.empty((hidden_size, 1, 1)))
        self.kappa = nn.Parameter(torch.empty((hidden_size, 1, 1)))
        self.w = nn.Parameter(torch.empty((hidden_size, 1, 1)))
        self.mu = nn.Parameter(torch.empty((hidden_size, 1, 1)))

        self.bn = nn.ModuleList([nn.BatchNorm2d(hidden_size, eps=1e-03, affine=True, track_running_stats=False) for i in range(2)])

        init.orthogonal_(self.w_inh)
        init.orthogonal_(self.w_exc)

        init.orthogonal_(self.i_w_gate.weight)
        init.orthogonal_(self.i_u_gate.weight)
        init.orthogonal_(self.e_w_gate.weight)
        init.orthogonal_(self.e_u_gate.weight)

        for bn in self.bn:
            init.constant_(bn.weight, 0.1)

        init.constant_(self.alpha, 1.)
        init.constant_(self.mu, 0.)
        # init.constant_(self.alpha, 0.1)
        # init.constant_(self.mu, 1)
        init.constant_(self.gamma, 0.)
        init.constant_(self.w, 1.)
        init.constant_(self.kappa, 1.)

        if self.use_attention:
            self.i_w_gate.bias.data = -self.a_w_gate.bias.data
            self.e_w_gate.bias.data = -self.a_w_gate.bias.data
            self.i_u_gate.bias.data = -self.a_u_gate.bias.data
            self.e_u_gate.bias.data = -self.a_u_gate.bias.data
        else:
            init.uniform_(self.i_w_gate.bias.data, 1, self.timesteps - 1)
            self.i_w_gate.bias.data.log()
            self.i_u_gate.bias.data.log()
            self.e_w_gate.bias.data = -self.i_w_gate.bias.data
            self.e_u_gate.bias.data = -self.i_u_gate.bias.data

    def forward(self, input_, inhibition, excitation,  activ=F.softplus, testmode=False):  # Worked with tanh and softplus
        # Attention gate: filter input_ and excitation
        # att_gate = torch.sigmoid(self.a_w_gate(input_) + self.a_u_gate(excitation))  # Attention Spotlight
        # att_gate = torch.sigmoid(self.a_w_gate(input_) * self.a_u_gate(excitation))  # Attention Spotlight
        if self.use_attention:
            # att_gate = torch.sigmoid(self.a_w_gate(inhibition) + self.a_u_gate(excitation))  # Attention Spotlight -- MOST RECENT WORKING
            att_gate = torch.sigmoid(self.a_w_gate(input_) + self.a_u_gate(excitation))  # Attention Spotlight -- MOST RECENT WORKING

        # Gate E/I with attention immediately
        if self.use_attention:
            gated_input = input_  # * att_gate  # In activ range
            gated_excitation = att_gate * excitation
            gated_inhibition = att_gate  # * inhibition
        else:
            gated_input = input_

        # Compute inhibition
        inh_intx = self.bn[0](F.conv2d(gated_excitation, self.w_inh, padding=self.h_padding))  # in activ range
        # inhibition_hat = activ(gated_input - inh_intx * (self.alpha * gated_inhibition + self.mu))
        # inhibition_hat = activ(gated_input - activ(inh_intx * (self.alpha * gated_inhibition + self.mu)))  # Older version
        inhibition_hat = activ(input_ - activ(inh_intx * (self.alpha * gated_inhibition + self.mu)))

        # Integrate inhibition
        inh_gate = torch.sigmoid(self.i_w_gate(gated_input) + self.i_u_gate(gated_inhibition))
        inhibition = (1 - inh_gate) * inhibition + inh_gate * inhibition_hat  # In activ range

        # Pass to excitatory neurons
        # exc_gate = torch.sigmoid(self.e_w_gate(inhibition) + self.e_u_gate(excitation))
        exc_gate = torch.sigmoid(self.e_w_gate(gated_inhibition) + self.e_u_gate(gated_excitation))
        exc_intx = self.bn[1](F.conv2d(inhibition, self.w_exc, padding=self.h_padding))  # In activ range
        # exc_intx = activ(exc_intx)
        # excitation_hat = activ(self.kappa * inhibition + self.gamma * exc_intx + self.w * inhibition * exc_intx)  # Skip connection OR add OR add by self-sim
        excitation_hat = activ(exc_intx * (self.kappa * inhibition + self.gamma))  # Skip connection OR add OR add by self-sim

        excitation = (1 - exc_gate) * excitation + exc_gate * excitation_hat
        if testmode:
            return inhibition, excitation, att_gate
        else:
            return inhibition, excitation

class FFhGRU(nn.Module):

    def __init__(self, dimensions, timesteps=8, kernel_size=15, jacobian_penalty=False, grad_method='bptt'):
        '''
        '''
        super(FFhGRU, self).__init__()
        self.timesteps = timesteps
        self.jacobian_penalty = jacobian_penalty
        self.grad_method = grad_method
        self.hgru_size = dimensions
        self.bn = nn.BatchNorm3d(self.hgru_size, eps=1e-03, track_running_stats=False)
        self.preproc = nn.Conv3d(3, dimensions, kernel_size=1, padding=1 // 2)
        # self.preproc = nn.Conv2d(3, dimensions, kernel_size=1, padding=1 // 2)
        # self.preproc = nn.Parameter(torch.empty((1, dimensions, 1, 1, 1)))
        # init.orthogonal_(self.preproc)
        self.unit1 = hConvGRUCell(
            hidden_size=self.hgru_size,
            kernel_size=kernel_size,
            use_attention=True,
            timesteps=timesteps)
        # self.bn = nn.BatchNorm2d(self.hgru_size, eps=1e-03, track_running_stats=False)
        # self.readout = nn.Linear(timesteps * self.hgru_size, 1) # the first 2 is for batch size, the second digit is for the dimension
        # self.readout_bn = nn.BatchNorm2d(self.hgru_size, eps=1e-03, track_running_stats=False)
        self.readout_conv = nn.Conv2d(dimensions, 1, 1)
        self.target_conv = nn.Conv2d(2, 1, 5, padding=5 // 2)
        torch.nn.init.zeros_(self.target_conv.bias)
        # self.target_conv_0 = nn.Conv2d(3, 16, 5, padding=0)  # padding=5 // 2)
        # self.target_pool_0 = nn.MaxPool2d(2, 2, padding=0)
        # self.target_conv_1 = nn.Conv2d(16, 16, 5, padding=0)  # padding=7 // 2)
        # self.target_pool_1 = nn.MaxPool2d(2, 2, padding=0)
        # self.target_conv_2 = nn.Conv2d(16, 1, 5, padding=0)  # padding=7 // 2)
        self.readout_dense = nn.Linear(1, 1)
        # torch.nn.init.zeros_(self.readout_dense.bias)
        self.nl = F.softplus

    def forward(self, x, testmode=False):
        # First step: replicate x over the channel dim self.hgru_size times
        xbn = self.preproc(x)
        # xbn = self.bn(xbn)  # This might be hurting me...
        xbn = self.nl(xbn)  # TEST TO SEE IF THE NL STABLIZES

        # Now run RNN
        x_shape = xbn.shape
        excitation = torch.zeros((x_shape[0], x_shape[1], x_shape[3], x_shape[4]), requires_grad=False).to(x.device)
        inhibition = torch.zeros((x_shape[0], x_shape[1], x_shape[3], x_shape[4]), requires_grad=False).to(x.device)
        # excitation = xbn.clone()[:, :, 0]
        # inhibition = xbn.clone()[:, :, 0]
        # with torch.no_grad():
        #     inhibition = xbn[:, :, 0].clone()

        # Loop over frames
        states = []
        gates = []
        for t in range(x_shape[2]):
            out = self.unit1(
                input_=xbn[:, :, t],
                inhibition=inhibition,
                excitation=excitation,
                activ=self.nl,
                testmode=testmode)
            if testmode:
                inhibition, excitation, gate = out
                gates.append(gate)  # This should learn to keep the winner
                states.append(self.readout_conv(excitation))  # This should learn to keep the winner
            else:
                inhibition, excitation = out
                # states.append(self.readout_conv(excitation))
                # if t == x_shape[2] - 1:
                #     states.append(self.readout_conv(excitation))  # This should learn to keep the winner

        # Conv 1x1 output
        # if testmode:
        #     out_states = [states[-1]]
        #     out_states.append(x[:, 2, 0][:, None])
        #     output = torch.cat(out_states, 1)  # .reshape(x_shape[0], -1)
        # else:
        # output = torch.cat([self.readout_conv(self.readout_bn(excitation)), x[:, 2, 0][:, None]], 1)

        output = torch.cat([self.readout_conv(excitation), x[:, 2, 0][:, None]], 1)
        # output = torch.cat(states, 1).mean(1, keepdim=True)  # Convert video -> spatial path
        # output = torch.cat([output, x[:, 1:, 0]], 1)  # Paste the start and end goals

        # Potentially combine target_conv + readout_bn into 1
        output = self.target_conv(output)  # output.sum(1, keepdim=True))  # 2 channels -> 1. Is the dot in the target?
        # output = self.target_conv(torch.cat([excitation, x[:, 2, 0][:, None]], 1))
        # # Mini readout network for solving PF without any clutter. RF=32x32
        # output = self.nl(self.target_conv_0(output))
        # output = self.target_pool_0(output)
        # output = self.nl(self.target_conv_1(output))
        # output = self.target_pool_0(output)
        # output = self.nl(self.target_conv_2(output))
        # if sum([*output.size()[2:]]) > 2:
        #     output = F.avg_pool2d(output, kernel_size=output.size()[2:])  # Spatial pool
        output = F.avg_pool2d(output, kernel_size=output.size()[2:])
        # output = self.readout_dense(output.reshape(x_shape[0], -1))  # scale + intercept
        output = output.reshape(x_shape[0], -1)
        output = self.readout_dense(output)
        pen_type = 'l1'
        jv_penalty = torch.tensor([1]).float().cuda()
        if testmode: return output, torch.stack(states, 1), torch.stack(gates, 1)
        return output, jv_penalty

class FFhGRU_v2(nn.Module):

    def __init__(self, dimensions, timesteps=8, kernel_size=15, jacobian_penalty=False, grad_method='bptt'):
        '''
        '''
        super(FFhGRU_v2, self).__init__()
        self.timesteps = timesteps
        self.jacobian_penalty = jacobian_penalty
        self.grad_method = grad_method
        self.hgru_size = dimensions
        # self.bn = nn.BatchNorm3d(self.hgru_size, eps=1e-03, track_running_stats=False)
        self.preproc = nn.Conv3d(3, dimensions, kernel_size=1, padding=1 // 2)
        # self.preproc = nn.Conv2d(3, dimensions, kernel_size=1, padding=1 // 2)
        # self.preproc = nn.Parameter(torch.empty((1, dimensions, 1, 1, 1)))
        # init.orthogonal_(self.preproc)
        self.unit1 = hConvGRUCell(
            hidden_size=self.hgru_size,
            kernel_size=kernel_size,
            use_attention=False,
            timesteps=timesteps)
        # self.bn = nn.BatchNorm2d(self.hgru_size, eps=1e-03, track_running_stats=False)
        # self.readout = nn.Linear(timesteps * self.hgru_size, 1) # the first 2 is for batch size, the second digit is for the dimension
        # self.readout_bn = nn.BatchNorm2d(self.hgru_size, eps=1e-03, track_running_stats=False)
        self.target_conv = nn.Conv2d(dimensions + 2, 1, 1)
        torch.nn.init.zeros_(self.target_conv.bias)
        # self.target_conv_0 = nn.Conv2d(3, 16, 5, padding=0)  # padding=5 // 2)
        # self.target_pool_0 = nn.MaxPool2d(2, 2, padding=0)
        # self.target_conv_1 = nn.Conv2d(16, 16, 5, padding=0)  # padding=7 // 2)
        # self.target_pool_1 = nn.MaxPool2d(2, 2, padding=0)
        # self.target_conv_2 = nn.Conv2d(16, 1, 5, padding=0)  # padding=7 // 2)
        # self.readout_dense = nn.Linear(1, 1)
        # torch.nn.init.zeros_(self.readout_dense.bias)
        self.nl = F.softplus

    def forward(self, x, testmode=False):
        # First step: replicate x over the channel dim self.hgru_size times
        xbn = self.preproc(x)
        # xbn = self.bn(prex)  # This might be hurting me...
        xbn = self.nl(xbn)  # TEST TO SEE IF THE NL STABLIZES

        # Now run RNN
        x_shape = xbn.shape
        excitation = torch.zeros((x_shape[0], x_shape[1], x_shape[3], x_shape[4]), requires_grad=False).to(x.device)
        inhibition = torch.zeros((x_shape[0], x_shape[1], x_shape[3], x_shape[4]), requires_grad=False).to(x.device)
        # with torch.no_grad():
        #     inhibition = xbn[:, :, 0].clone()

        # Loop over frames
        states = []
        gates = []
        for t in range(x_shape[2]):
            out = self.unit1(
                input_=xbn[:, :, t],
                inhibition=inhibition,
                excitation=excitation,
                activ=self.nl,
                testmode=testmode)
            if testmode:
                inhibition, excitation, gate = out
                gates.append(gate)  # This should learn to keep the winner
                states.append(excitation)  # This should learn to keep the winner
            else:
                inhibition, excitation = out
                # states.append(self.readout_conv(excitation))
                # if t == x_shape[2] - 1:
                #     states.append(self.readout_conv(excitation))  # This should learn to keep the winner

        # Potentially combine target_conv + readout_bn into 1
        output = self.target_conv(torch.cat([excitation, x[:, 1:, 0]], 1))  # 2 channels -> 1. Is the dot in the target?
        # # Mini readout network for solving PF without any clutter. RF=32x32
        # output = self.nl(self.target_conv_0(output))
        # output = self.target_pool_0(output)
        # output = self.nl(self.target_conv_1(output))
        # output = self.target_pool_0(output)
        # output = self.nl(self.target_conv_2(output))
        # if sum([*output.size()[2:]]) > 2:
        #     output = F.avg_pool2d(output, kernel_size=output.size()[2:])  # Spatial pool
        output = F.avg_pool2d(output, kernel_size=output.size()[2:])
        # output = self.readout_dense(output.reshape(x_shape[0], -1))  # scale + intercept
        output = output.reshape(x_shape[0], -1)
        pen_type = 'l1'
        jv_penalty = torch.tensor([1]).float().cuda()
        if testmode: return output, torch.stack(states, 1), torch.stack(gates, 1)
        return output, jv_penalty

class FC(nn.Module):

    def __init__(self, dimensions, timesteps=8, kernel_size=15, jacobian_penalty=False, grad_method='bptt'):
        '''
        '''
        super(FC, self).__init__()
        self.timesteps = timesteps
        self.jacobian_penalty = jacobian_penalty
        self.grad_method = grad_method
        self.hgru_size = dimensions
        self.bn = nn.BatchNorm3d(self.hgru_size, eps=1e-03, track_running_stats=False)
        self.preproc = nn.Conv3d(3, dimensions, kernel_size=1, padding=1 // 2)
        self.readout = nn.Linear(64*32*32*32, 1) # the first 2 is for batch size, the second digit is for the dimension
        # self.readout = nn.Linear(timesteps * self.hgru_size, 1) # the first 2 is for batch size, the second digit is for the dimension

    def forward(self, x, testmode=False):
        # First step: replicate x over the channel dim self.hgru_size times
        # x = x.repeat(1, self.hgru_size, 1, 1, 1)
        x = self.preproc(x)
        x = self.bn(x)
        x_shape = x.shape
        x = self.readout(x.reshape(x_shape[0], -1))
        jv_penalty = torch.tensor([1]).float().cuda()
        return x, jv_penalty

class ClockHGRU(nn.Module):

    def __init__(self, dimensions, timesteps=8, kernel_size=15, jacobian_penalty=False, grad_method='bptt', clock_type="dynamic"):
        '''
        '''
        super(ClockHGRU, self).__init__()
        assert clock_type in ["fixed", "dynamic"]
        self.clock_type = clock_type
        self.timesteps = timesteps
        self.jacobian_penalty = jacobian_penalty
        self.grad_method = grad_method
        self.hgru_size = dimensions

        self.preproc = nn.Conv3d(3, dimensions, kernel_size=1, padding=1 // 2)
        self.unit1 = ClockHConvGRUCell(
            hidden_size=self.hgru_size,
            kernel_size=kernel_size,
            clock_type=clock_type,
            timesteps=timesteps)
        # self.bn = nn.BatchNorm3d(self.hgru_size, eps=1e-03, track_running_stats=False)
        self.bn = nn.BatchNorm3d(self.hgru_size, eps=1e-03, track_running_stats=True)
        self.readout_conv = nn.Conv2d(dimensions, 1, 1)
        # self.readout_dense = nn.Linear(262144, 1)
        # self.readout_dense = nn.Linear(1048576, 1)
        self.readout_dense = nn.Linear(65536, 1)

    def forward(self, x, testmode=False):
        # First step: replicate x over the channel dim self.hgru_size times
        x = self.preproc(x)
        x = self.bn(x)

        # Now run RNN
        x_shape = x.shape
        excitation = torch.zeros((x_shape[0], x_shape[1], x_shape[3], x_shape[4]), requires_grad=False, device=x.device)
        inhibition = torch.zeros((x_shape[0], x_shape[1], x_shape[3], x_shape[4]), requires_grad=False, device=x.device)

        # Loop over frames
        state_2nd_last = None
        states = []
        for t in range(x_shape[2]):
            inhibition, excitation = self.unit1(
                input_=x[:, :, t],
                step=t,  # torch.as_tensor(t, device=x.device).float(),
                inhibition=inhibition,
                excitation=excitation)
            if t == self.timesteps - 2 and "rbp" in self.grad_method:
                state_2nd_last = excitation
            elif t == self.timesteps - 1:
                last_state = excitation
            # states.append(F.max_pool2d(self.readout_conv(excitation), kernel_size=excitation.size()[2:]))
            states.append(self.readout_conv(excitation))

        # Use the final frame to make a decision
        # output = self.bn(torch.cat(states, -1))  # Stack as timesteps
        # output = F.max_pool2d(output, kernel_size=2)

        # Fully connected output, gets down to 0.35-ish loss
        # output = self.readout_dense(torch.cat(states, -1).reshape(x_shape[0], -1))

        # Conv 1x1 output
        output = self.readout_dense(torch.cat(states,-1).reshape(x_shape[0], -1))

        # output = self.readout_conv(output)
        # output = F.avg_pool2d(output, kernel_size=output.size()[2:])
        # output = self.readout_dense(output.reshape(x_shape[0], -1))
        # output = excitation.mean(dim=(2, 3))
        # output = torch.stack(states, -1)
        # output = output.reshape(x_shape[0], -1)
        # output = self.readout(output)

        pen_type = 'l1'
        jv_penalty = torch.tensor([1]).float().cuda()
        # mu = 0.9
        # double_neg = False
        # if self.training and self.jacobian_penalty:
        #     if pen_type == 'l1':
        #         norm_1_vect = torch.ones_like(last_state)
        #         norm_1_vect.requires_grad = False
        #         jv_prod = torch.autograd.grad(last_state, state_2nd_last, grad_outputs=[norm_1_vect], retain_graph=True,
        #                                       create_graph=self.jacobian_penalty, allow_unused=True)[0]
        #         jv_penalty = (jv_prod - mu).clamp(0) ** 2
        #         if double_neg is True:
        #             neg_norm_1_vect = -1 * norm_1_vect.clone()
        #             jv_prod = torch.autograd.grad(last_state, state_2nd_last, grad_outputs=[neg_norm_1_vect], retain_graph=True,
        #                                           create_graph=True, allow_unused=True)[0]
        #             jv_penalty2 = (jv_prod - mu).clamp(0) ** 2
        #             jv_penalty = jv_penalty + jv_penalty2
        #     elif pen_type == 'idloss':
        #         norm_1_vect = torch.rand_like(last_state).requires_grad_()
        #         jv_prod = torch.autograd.grad(last_state, state_2nd_last, grad_outputs=[norm_1_vect], retain_graph=True,
        #                                       create_graph=True, allow_unused=True)[0]
        #         jv_penalty = (jv_prod - norm_1_vect) ** 2
        #         jv_penalty = jv_penalty.mean()
        #         if torch.isnan(jv_penalty).sum() > 0:
        #             raise ValueError('Nan encountered in penalty')
        if testmode: return output, states
        return output, jv_penalty


from libqtile.lazy import lazy
from libqtile.config import Group, Key
from sections.keys import keys  # >> ignore this error
from global_variables import mod

#  groups = [Group(i) for i in "123456789"]
group_names = [
    "1",
    "2",
    "3",
    "4",
    "5",
]

groups = []

group_labels = [
    " ",
    #  " ",
    " ",
    "󰎆 ",
    " ",
    " ",
]

group_layouts = [
    "max",
    "max",
    "max",
    "max",
    "max",
    "max",
]

group_match_apps = ["firefox"]

for i in range(len(group_names)):
    groups.append(
        Group(
            name=group_names[i],
            layout=group_layouts[i].lower(),
            label=group_labels[i],
            #  match=[Match(wm_class=[group_match_apps[i]])],
        )
    )

for i in groups:
    keys.extend(
        [
            # mod1 + letter of group = switch to group
            Key(
                [mod],
                i.name,
                lazy.group[i.name].toscreen(),
                desc="Switch to group {}".format(i.name),
            ),
            # mod1 + shift + letter of group = switch to & move focused window to group
            Key(
                [mod, "shift"],
                i.name,
                lazy.window.togroup(i.name, switch_group=True),
                desc="Switch to & move focused window to group {}".format(i.name),
            ),
            # Or, use below if you prefer not to switch to that group.
            #  mod1 + shift + letter of group = move focused window to group
            #  Key(
            #      [mod, "shift"],
            #      i.name,
            #      lazy.window.togroup(i.name),
            #      desc="move focused window to group {}".format(i.name),
            #  ),
        ]
    )


# Tristan Rojo
# Challenge 2: Fibonacci USA (via System Arguments)
# The script takes an integer system argument (n); prints the list of n numbers and the nth value in the Fibonacci Sequence

# Comments: Only error-proof in negative integers

import sys

def fibonacci(num): # say n = 20

    if num == 1:
        return 1

    elif num == 2:
        return 1

    else:
        n1 = 1
        n2 = 1

        list = []
        list.append(n1)
        list.append(n2)

        for i in range(num-2):
            nth = n2 + n1
            list.append(nth)
            temp = n2
            n2 = nth
            n1 = temp

    print (list)
    return (list[num-1])

if len(sys.argv) == 2:

    n = sys.argv[1]

    while (int(n)<=0):

        n = (input('Enter a Positive Integer:'))

    print ('The', str(n) +'th value:', fibonacci(int(n)))

else:
    print ("***No input from sys.argv[1]")
    print ()

    n = input("Enter a Positive Integer: ")

    while (int(n)<=0):

        n = (input('Enter a Positive Integer:'))

    print ('The', str(n) +'th value:', fibonacci(int(n)))


import time

DEFAULT_FMT = '[{elapsed:0.8f}s] {name}({args}) -> {result}'

def clock(fmt=DEFAULT_FMT):
    def decorate(func):  # 真正的装饰器
        def clocked(*_args):  # 包装被装饰的函数
            t0 = time.perf_counter()
            _result = func(*_args)
            elapsed = time.perf_counter() - t0
            name = func.__name__
            args = ', '.join(repr(arg) for arg in _args)
            result = repr(_result)
            print(locals())
            print(fmt.format(**locals()))  # **locals() 为了在 fmt 中引用 clocked 的局部变量
            return _result  # clocked 将取代被装饰的函数，因此它应该返回被装饰的函数返回值

        return clocked

    return decorate

if __name__ == '__main__':
    @clock()
    def snooze(seconds):
        time.sleep(seconds)

    for i in range(3):
        snooze(.123)

流畅的python/09_装饰器和闭包/9.10_参数化装饰器/02_clock装饰器函数实现.py


# -*- coding:utf-8 -*-
import urllib
import requests
import re
import lxml.html.soupparser as soupparser
import lxml.etree as etree
from pyquery import PyQuery as pq
__demoUrl__ = "http://mp.weixin.qq.com/s?__biz=OTE4MzAyODYx&mid=400183897&idx=1&sn=56e62f1bf0c15669e67264494485c1a0&3rd=MzA3MDU4NTYzMw==&scene=6#rd"
class Eric_crawler(object):
    def crawler(self,url):
        sock = urllib.urlopen(url)
        htmlSource = sock.read()
        sock.close()
        dom = soupparser.fromstring(htmlSource)
        etree.tostring(dom)
        return dom
    def origin(self,url):
        dom = self.crawler(url)
        #print htmlSource
        origin_flag = dom.xpath('//*[@id="copyright_logo"]')
        #print origin_flag[0].text
        if origin_flag:
            status = 200
        else:
            status = 201
        #print status
        return status

    def biz(self,url):
        r = pq(requests.get(url).text)
        strScript =  r.find('script').text()
        biz = re.findall('var appuin = "(.*?)";',strScript)
        return biz


numbers = []

while True:
    number = input()
    if number == '0':
        break
    numbers.append(number)

for number in numbers:
    sum = 0
    for i in range(len(number)):
        sum += int(number[i])
    print(sum)


import unittest
import sys
from io import StringIO
from main import *

class UserDefinedFunctionsTests(unittest.TestCase):
    def test_main(self):
        # Make sure there is no return statement.
        self.assertIsNone(say_hello())

    def test_function_name(self):
        # Make sure that the function has the correct name.
        f = open('main.py')
        lines = str(f.readlines())
        f.close()
        self.assertRegex(lines, 'say_hello()', msg="The name of the function is incorrect.")

    def test_output(self):
        # Make sure that calling say_hello() outputs the correct string.
        saved_stdout = sys.stdout
        try:
            out = StringIO()
            sys.stdout = out
            say_hello()
            output = out.getvalue().strip()
            assert output == "Hello World!"
        finally:
            sys.stdout = saved_stdout


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

# 分布式进程通信 ——> master管理者

import random, time, queue
from multiprocessing.managers import BaseManager
from multiprocessing import freeze_support

# 发送任务的队列：
task_queue = queue.Queue()
# 接受结果队列
result_queue = queue.Queue()

# 从BaseManger继承QueueManger
class QueueManager(BaseManager):
  pass

## windows不支持register(callable)下调用匿名函数所以封装两个函数
def ret_task():
  global task_queue
  return task_queue
def ret_result():
  global result_queue
  return result_queue

# 将两个Queue都注册到网络上call参数关联Queue对象，使用lambda将queue返回出去
QueueManager.register('get_task_queue', callable=ret_task)
QueueManager.register('get_result_queue', callable=ret_result)
# 将manger绑定到5000端口，并设置验证码用于连接
manager = QueueManager(address=('127.0.0.1', 5000), authkey=b'xzxldl55')

if __name__ == '__main__':
  # 启动manger
  manager.start()
  # 获得通过网络访问到的Queue对象：（由于在同一个文件模块内，所以不需要通过网络访问，直接获得）
  task = manager.get_task_queue()
  result = manager.get_result_queue()
  # 放置几个任务（但不负责运行任务，运行任务交付由另一进程执行）
  for i in range(10):
    n = random.randint(0, 10000)
    print('放置任务 %d' % n)
    task.put(n)
  # 读取result队列
  print('读取结果中...')
  for i in range(10):
    r = result.get(timeout=100)
    print('结果为：%s' % r)
  # 关闭
  manager.shutdown()
  print('master 退出')


import cv2

def main():
    # Địa chỉ IP của camera
    IP_ADDRESS = '192.168.0.96'

    # Tạo đối tượng VideoCapture để kết nối và đọc frame từ camera
    cap = cv2.VideoCapture('rtsp://' + IP_ADDRESS + '/live/ch00_1')

    # Kiểm tra xem kết nối đã được thiết lập thành công hay chưa
    if not cap.isOpened():
        print("Không thể kết nối đến camera.")
        return

    while True:
        # Đọc frame từ camera
        ret, frame = cap.read()

        # Kiểm tra xem frame có được đọc thành công hay không
        if not ret:
            print("Không thể đọc frame từ camera.")
            break

        # Hiển thị frame lên màn hình
        cv2.imshow('Camera', frame)

        # Kiểm tra xem người dùng đã nhấn phím 'q' để thoát hay không
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # Giải phóng tài nguyên
    cap.release()
    cv2.destroyAllWindows()

if __name__ == '__main__':
    main()


import io
import pytest
from fastapi import status
from zipfile import ZipFile
from jsonschema import validate

from app.test.schema.schema_giver import (
    schema_fetch_product_ids,
    schema_fetch_product_origins,
    schema_fetch_product_origins_headers,
    schema_fetch_product,
    schema_fetch_product_headers,
    schema_fetch_gallery,
    schema_fetch_gallery_headers,
)

@pytest.mark.fetch_product_ids
@pytest.mark.asyncio
async def test_fetch_product_ids(async_client, token_header):
    response = await async_client.get(
        url="products/id",
        headers=token_header,
    )

    assert response.status_code == status.HTTP_200_OK
    data = response.json()
    assert validate(data, schema_fetch_product_ids) is None

@pytest.mark.fetch_product_origins
@pytest.mark.asyncio
async def test_fetch_product_origins(async_client, token_header):
    response = await async_client.get(
        "products/origin",
        headers=token_header,
    )

    assert response.status_code == status.HTTP_200_OK

    with ZipFile(io.BytesIO(response._content), "r") as zipfile:
        name_list = zipfile.namelist()
        assert validate(name_list, schema_fetch_product_origins) is None

    assert validate(dict(response.headers), schema_fetch_product_origins_headers) is None

@pytest.mark.fetch_product
@pytest.mark.asyncio
async def test_fetch_product(async_client, token_header, product_id):
    response = await async_client.get(
        f"products/{product_id}",
        headers=token_header,
    )

    assert response.status_code == status.HTTP_200_OK

    with ZipFile(io.BytesIO(response._content), "r") as zipfile:
        name_list = zipfile.namelist()
        assert validate(name_list, schema_fetch_product) is None

    assert validate(dict(response.headers), schema_fetch_product_headers) is None

@pytest.mark.fetch_gallery
@pytest.mark.asyncio
async def test_fetch_gallery(async_client):
    gallery_num = 3

    response = await async_client.get(f"products/gallery/{gallery_num}")

    assert response.status_code == status.HTTP_200_OK

    with ZipFile(io.BytesIO(response._content), "r") as zipfile:
        name_list = zipfile.namelist()
        assert validate(name_list, schema_fetch_gallery) is None

    assert validate(dict(response.headers), schema_fetch_gallery_headers) is None


# 방문 정보를 리스트로 표현
visited = [False] * 9

# 각 노드가 연결된 정보를 2차원 리스트로 표현
graph = [
    [],
    [2, 3, 8],
    [1, 7],
    [1, 4, 5],
    [3, 5],
    [3, 4],
    [7],
    [2, 6, 8],
    [1, 7]
]

def DFS(graph, v, visited):
    visited[v] = True  # 현재 노드 방문 처리
    print(v, end=' ')

    for i in graph[v]:
        if not visited[i]:
            # 현재 노드와 연결된 다른 노드들을 재귀적으로 방문
            DFS(graph, i, visited)

DFS(graph, 1, visited)


import pdfminer
import argparse
from pdfminer.high_level import extract_text
import json
import requests
from hashlib import md5
import random
import time

def read_config(config_path):
    config_fr = open(config_path, encoding="utf-8")
    config = json.load(config_fr)
    config_fr.close()
    return config["appid"], config["key"]

def MD5(message):
    MD5_message = md5(message.encode('utf-8')).hexdigest()
    return MD5_message

def translate(q, appid, key):
    salt = random.randint(1000000000, 9999999999)
    sign = MD5(appid + q + str(salt) + key)
    url = "http://api.fanyi.baidu.com/api/trans/vip/translate?q=" + q + "&from=en&to=zh&appid=" + appid + "&salt=" + str(salt) + "&sign=" + sign
    try:
        r = requests.get(url)
        res_dict = json.loads(r.text)
        translated_message = res_dict["trans_result"][0]["dst"]
        return translated_message
    except:
        return "error"

def main():
    dirname, filename = os.path.split(os.path.abspath(sys.argv[0]))
    appid, key = read_config(dirname + "\pdf_translate_config.json")

    parser = argparse.ArgumentParser(description="将PDF中的文本抽取为txt")
    parser.add_argument("-f", "--file", help="PDF文件名", dest="source_file", type=str)
    parser.add_argument("-o", "--output", help="输出文件的文件名", dest="output_file", default="none", type=str)
    args = parser.parse_args()

    text = extract_text(args.source_file)
    text = text.replace("\n\n", " ")
    text = text.replace("\n", " ")
    while(text.find("  ") != -1):
        text = text.replace("  ", " ")

    sentences = text.split(". ")
    total_count = str(len(sentences))

    if args.output_file == "none":
        output = args.source_file.replace(".pdf", "") + " chinese.txt"
    else:
        output = args.output_file

    with open(output, "w", encoding="utf-8") as fw:
        fw.write("")
    fw.close()

    index = 1
    for sentence in sentences:
        sentence = sentence + "."
        translated_sentence = translate(sentence, appid, key)
        if translated_sentence != "error":
            with open(output, "a", encoding="utf-8") as fw_t:
                fw_t.write(translated_sentence + "\n")
            fw_t.close()
            print("Translate:\t" + str(index) + "/" + total_count)
        else:
            print("ERROR:\t" + str(index) + "/" + total_count)
        index += 1
        time.sleep(1)

    print("**************\nALL DONE\n**************")

if __name__ == "__main__":
    main()


def leiaInt(mgn):
    while True:
        try:
            n = int(input(mgn))
        except (ValueError, TypeError):
            print('Erro: Digite um número inteiro válido')
        except Exception as erro:
            print(erro.__cause__, erro.__class__)
        else:
            return  n
            break

def leiaReal(mgn):
    while True:
        try:
            f = float(input(mgn))
        except (ValueError, TypeError):
            print('Erro: Digite um número real válido')
        except Exception as erro:
            print(erro.__cause__, erro.__class__)
        except KeyboardInterrupt:
            f = 0
            return f
            break
        else:
            return f
            break

i = leiaInt('Digite um número Inteiro:  ')
f = leiaReal('Digite um número Real: ')
print(f'O valor inteiro digitado foi {i} e o valor rela foi {f}')


import os
import ctypes
import pickle
import logging
from sys import exit
from argparse import ArgumentParser, Namespace

def init_argparse() -> ArgumentParser:
    parser = ArgumentParser(
        description=(
            "Allows for command line configuration of the Dark Blue generator and"
            " scoring engine."
        )
    )

    parser.add_argument(
        "-f", "--filepath", type=str, help="Path to Dark Blue JSON file."
    )

    parser.add_argument(
        "-c",
        "--command-line",
        help=(
            "(Not implemented, GUI in progress) Set generator and scoring engine to"
            " run in command-line only mode instead of GUI mode."
        ),
        action="store_true",
    )

    parser.add_argument(
        "-s",
        "--scoring-only",
        help=(
            "Do not run the generator, instead only configure and run the scoring"
            " engine."
        ),
        action="store_true",
    )

    parser.add_argument(
        "-g",
        "--generator-only",
        help=(
            "The generator will run without configuring or running the scoring engine."
        ),
        action="store_true",
    )

    parser.add_argument(
        "-d",
        "--debug",
        help="Enables debug logging output for generator and scoring engine.",
        action="store_true",
    )

    parser.add_argument(
        "-v",
        "--full-debug",
        help=(
            "(Not implemented) Scoring engine will write the configuration of each"
            " object to the HTML scoring report"
        ),
        action="store_true",
    )

    parser.add_argument(
        "-l",
        "--log",
        type=str,
        help="Path to where the log file will be written.",
    )

    parser.add_argument(
        "-i", "--interval", type=int, help="Length of scoring engine interval."
    )

    parser.add_argument(
        "-n",
        "--notifications",
        help="Disables notifications. Notifications are enabled by default.",
        action="store_false",
    )

    parser.add_argument(
        "-r",
        "--resume",
        help="Resumes scoring a saved scoring engine image.",
        action="store_true",
    )

    return parser

def init_generator_windows(args: Namespace):
    from utils.generator.windows.generator_windows import WindowsGenerator

    scoring_interval = 30

    if args.interval is not None:
        scoring_interval = args.interval

    generator = WindowsGenerator(
        filepath=args.filepath,
        debug=args.debug,
        generator_only=args.generator_only,
        scoring_only=args.scoring_only,
        log_path=args.log,
        full_debug=args.full_debug,
        scoring_interval=scoring_interval,
        notifications=args.notifications,
    )

    return generator

def init_generator_linux(args: Namespace):
    from utils.generator.linux.generator_linux import LinuxGenerator

    scoring_interval = 30

    if args.interval is not None:
        scoring_interval = args.interval

    generator = LinuxGenerator(
        filepath=args.filepath,
        debug=args.debug,
        generator_only=args.generator_only,
        scoring_only=args.scoring_only,
        log_path=args.log,
        full_debug=args.full_debug,
        scoring_interval=scoring_interval,
        notifications=args.notifications,
    )

    return generator

def check_arguments(args: Namespace) -> True:
    if args.filepath is None and not args.scoring_only and not args.resume:
        print("Please specify path to a Dark Blue JSON configuration file.")
        return False

    return True

def data_warning() -> bool:

    print(
        "\nWARNING: READ THE FOLLOWING CAREFULLY.\n\nRunning the generator MAY RESULT"
        " IN LOSS OF DATA OR OPERATING SYSTEM FUNCTIONALITY.\nBy using the Dark Blue"
        " CyberPatriot Training Tool, you assume full risk for the use of the tool as"
        " specified in the license agreement.\nDark Blue SHOULD ONLY BE USED ON VIRTUAL"
        " MACHINES created for the purpose of training.\n"
    )

    response = input(
        "\nPlease verify you have read the above, and understand that any data on this"
        " current system may be destroyed by entering yes or no [y/N]: "
    )

    if response.lower() in ["yes", "y", "accept", "ok", "okay"]:
        return True
    else:
        return False

def resume_scoring():

    print("Attempting to resume scoring engine from saved image...")

    saved_path = None

    if os.name == "nt":
        saved_path = os.path.join(os.environ["LOCALAPPDATA"], "DarkBlue")
    elif os.name == "posix":
        saved_path = os.path.join(os.environ["HOME"], ".darkblue")

    if os.path.exists(saved_path):
        scoring_engine_path = os.path.join(saved_path, "dark_blue_scoring_engine.dat")

        if os.path.exists(scoring_engine_path):

            try:
                with open(scoring_engine_path, "rb") as input_file:
                    scoring_engine = pickle.load(input_file)

                    if scoring_engine is not None:
                        scoring_engine.start()
            except Exception as e:
                logging.critical(
                    "Could not resume scoring engine. Error message: {}".format(e)
                )
                print(
                    "Error: Could not resume scoring engine.\nError during resume: {}"
                    .format(e)
                )
                exit(-10)

def initialize_logger(args: Namespace) -> None:
    # Defaults for log level and log path.
    log_path = "darkblue.log"
    log_level = 20

    # Initialize logger to specified path if the logging flag is set.
    if args.log is not None and args.log != "":
        log_path = args.log

    if args.debug:
        log_level = 10

    try:
        logging.basicConfig(
            filename=log_path,
            level=log_level,
            filemode="w",
            format="%(asctime)s - %(levelname)s - %(message)s",
        )
    except FileNotFoundError:
        print(
            "\nERROR: Could not start logger with the specified path: {}".format(
                log_path
            )
        )
        print(
            "Logging currently can't create missing directories in the path, so any"
            " directories may have to be created manually."
        )
        print(
            "Logger will initialize using the default path in the same directory as the"
            " Dark Blue executable."
        )

        logging.basicConfig(
            filename="darkblue.log",
            level=log_level,
            filemode="w",
            format="%(asctime)s - %(levelname)s - %(message)s",
        )

def main():
    parser = init_argparse()
    args = parser.parse_args()

    valid = check_arguments(args=args)
    initialize_logger(args=args)

    if not valid:
        exit(-1)

    if not args.scoring_only and not args.resume and os.name == "nt":
        is_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0

        if not is_admin:
            print(
                "\nPlease run Dark Blue from an Administrator prompt. The generator"
                " requires administrative privileges.\n"
            )
            exit(-1)

    if args.command_line and not args.scoring_only and not args.resume:
        acknowledgement = data_warning()

        if not acknowledgement:
            print("Exiting...")
            exit(-2)

    if not args.resume:
        generator = None

        if os.name == "nt":
            generator = init_generator_windows(args=args)
        elif os.name == "posix":
            generator = init_generator_linux(args=args)

        if generator is None:
            print("Generator could not be initialized.")
            exit(-20)

        if args.full_debug:
            print(generator)

        generator.generate_image()

        generator.scoring_engine.start()
    elif args.resume:
        resume_scoring()

if __name__ == "__main__":
    main()


#!/usr/bin/python
# -*- coding: utf-8 -*-
"""The main program of HMM.

This script serves as the main program to implement HMM by calling other
modules.
"""

import BaumWelch
import Viterbi
import AEMatrices
import Sequences
import argparse
import sys
import os

def viterbiAlgorithm(seq, a, e):
	"""Run the Viterbi algorithm and saves the Viterbi Matrix and the Back Trace Matrix in an output folder.
	"""
	# Read the A and E matrices
	AEMatrices.init(e, a)

	# Read the input sequence(s) and store them into setX
	setX = Sequences.readSeq(seq, "X")

	# Perform the Viterbi algorithm on the first sequence of the set setX
	# and store the viterbi matrix in the variable vi and the back trace matrix in variable backTrace
	(vi, backTrace, probability) = Viterbi.viterbi(setX[0])

	# Print the output matrices of Viterbi algorithm
	Viterbi.writePathMatrix(vi, setX[0], "output/ViterbiMatrix.tsv")
	Viterbi.writePathMatrix(backTrace, setX[0], "output/BackTraceMatrix.tsv")
	#Print the vitervi path instead of the vitervi backtrace
	with open('ViterbiPath.txt', 'w') as text_file:
		print('Path: {}.'.format(Viterbi.generateStateSeq(backTrace, setX[0])), file = text_file)

	# Print the most likely sequence path of x according to the viterbi algorithm
	print('Most likely state is {0}, with probability of {1}'.format(''.join(Viterbi.generateStateSeq(backTrace, setX[0])), probability))

def forwardAlgorithm(seq, a, e):
	"""Prints the forward probability for a given sequence"""
	# Read the A and E matrices
	AEMatrices.init(e, a)

	# Read the input sequence(s) and store them into setX
	setX = Sequences.readSeq(seq, "X")

	# Obtain the forward matrix
	f = BaumWelch.forward(setX[0], len(setX[0]) - 2)
	AEMatrices.writeForwardMatrix(f, 'output/forward_matrix.tsv')
	print('\nForward probability for sequence {0}:\n{1}'.format(''.join(setX[0]).strip(), BaumWelch.getProbabilityForwardX(f, len(setX[0]) - 2)))

def backwardAlgorithm(seq, a, e):
	"""Prints the backward probability for a given sequence"""
	# Read the A and E matrices
	AEMatrices.init(e, a)

	# Read the input sequence(s) and store them into setX
	setX = Sequences.readSeq(seq, "X")

	# Obtain the backward matrix
	b = BaumWelch.backward(setX[0], len(setX[0]) - 2)
	AEMatrices.writeBackwardMatrix(b, 'output/backward_matrix.tsv')
	print('\nBackward probability for sequence {0}:\n{1}'.format(''.join(setX[0]).strip(), b['B'][0]))

def baum_welchAlgorithm(seq, a, e, convergence):
	"""Performe the Baum Welch algorithm. If convergence is true, then it should perform the training (for you to code)"""
	# Read the A and E matrices
	AEMatrices.init(e, a)
	print(a)

	# Read the input sequence(s) and store them into setX
	setX = Sequences.readSeq(seq, "X")

	w = BaumWelch.baumWelch(setX, convergence)

	print("\n SummLL is")
	print(w[2])
	# Number of iterations, at this point there is already one iteration
	max_i = 1
	AEMatrices.writeAMatrix(w[0], 'output/NewA.tsv')
	AEMatrices.writeEMatrix(w[1], 'output/NewE.tsv')

### Iterate the training until convergence or until max iter nº

	while (convergence) and (max_i < 15):
		#Uses the new transition and emision probabilities calculated in the last B-W training
		print("\n Iteration number")
		print(max_i)
		prev_sum_LL = w[2]
		AEMatrices.init('output/NewE.tsv', 'output/NewA.tsv')
		w = BaumWelch.baumWelch(setX, convergence)
		print("\n New A and E")
		sum_LL = w[2]
		print(w[0])
		print("\n")
		print(w[1])
		print("\n SummLL is")
		print(w[2])
		max_i = max_i + 1
		AEMatrices.writeAMatrix(w[0], 'output/NewA.tsv')
		AEMatrices.writeEMatrix(w[1], 'output/NewE.tsv')
		# Set the stop criterium
		converg_num = sum_LL - prev_sum_LL
		print(converg_num)
		#if (converg_num == 0.0):
			#convergence = False

def parser():
	"""Retrieves the arguments from the command line.
	"""

	parser = argparse.ArgumentParser(description='A program to run HMM algorithms.')

	parser.add_argument('-v', dest='viterbi', action='store_true', help='[-v] to run the Viterbi algorithm')
	parser.add_argument('-f', dest='forward', action='store_true', help='[-f] to run the Forward algorithm')
	parser.add_argument('-b', dest='backward', action='store_true', help='[-b] to run the Backward algorithm')
	parser.add_argument('-w', dest='baum_welch', action='store_true', help='[-w] to run the Baum-Welch algorithm')
	parser.add_argument('-c', dest='convergence', action='store_true',
						help='[-c] to reach convergence, leave empty for doing only 1 iteration', default=False)
	parser.add_argument('-am', required=True, metavar='transmission_matrix_file', dest='transitionMatrix',
						help='[-am] to select transmission matrix file')
	parser.add_argument('-em', required=True, metavar='emission_matrix_file', dest='emissionMatrix',
						help='[-em] to select emission matrixfile ')
	parser.add_argument('-s', required=True, metavar='sequence_file', dest='sequence',
						help='[-s] to select sequence file')

	arguments = parser.parse_args()  # takes the arguments

	if arguments.viterbi == True:  # Do the Viterbi algorithm
		algorithm = 'viterbi'
	elif arguments.forward == True:  # Do the forward_backward algorithm
		algorithm = 'forward'
	elif arguments.backward == True:  # Do the forward_backward algorithm
		algorithm = 'backward'
	elif arguments.baum_welch == True:  # Do the Baum-Welch algorithm
		algorithm = 'baum_welch'

	# Kept here just in case
	else:
		print('This shouldn\'t happen')
		sys.exit()

	return [algorithm, arguments]

def main():
	"""Main function. This function checks the chosen arguments and files and calls the right function.
	"""
	if not os.path.exists('output'):
		os.makedirs('output')

	algorithm, args = parser()

	input_sequence = args.sequence
	a_matrix = args.transitionMatrix
	e_matrix = args.emissionMatrix

	if algorithm == 'viterbi':
		viterbiAlgorithm(input_sequence, a_matrix, e_matrix)
	elif algorithm == 'forward':
		forwardAlgorithm(input_sequence, a_matrix, e_matrix)
	elif algorithm == 'backward':
		backwardAlgorithm(input_sequence, a_matrix, e_matrix)
	elif algorithm == 'baum_welch':
		baum_welchAlgorithm(input_sequence, a_matrix, e_matrix, args.convergence)

if __name__ == "__main__":
	main()

print('\n"A hidden connection is stronger than an obvious one."\n-Heraclitus of Ephesus\n')


"""
Reproduces the sensitivity example from
https://github.com/casadi/casadi/blob/develop/docs/examples/python/nlp_sensitivities.py
"""

import time
from typing import Tuple

import casadi as cs
import matplotlib.pyplot as plt
import numpy as np
from numpy.polynomial import Polynomial

from csnlp import Nlp, wrappers
from csnlp.core.data import array2cs, cs2array

plt.style.use("bmh")

def get_coeffs(d: int) -> Tuple[cs.DM, cs.DM, cs.DM]:
    """Gets the coefficients of the collocation equation, of the continuity equation,
    and lastly of the quadrature function."""
    tau_root = np.append(0, cs.collocation_points(d, "legendre"))
    C = cs.DM.zeros(d + 1, d + 1)
    D = cs.DM.zeros(d + 1)
    B = cs.DM.zeros(d + 1)
    for j in range(d + 1):
        p = Polynomial([1])
        for r in range(d + 1):
            if r != j:
                p *= Polynomial([-tau_root[r], 1]) / (tau_root[j] - tau_root[r])
        D[j] = p(1.0)
        pder = p.deriv()
        for r in range(d + 1):
            C[j, r] = pder(tau_root[r])
        pint = p.integ()
        B[j] = pint(1.0)
    return C, D, B

def get_dynamics_and_cost() -> cs.Function:
    """Returns the dynamics and objective function of the problem."""
    x1 = cs.SX.sym("x1")
    x2 = cs.SX.sym("x2")
    x = cs.vertcat(x1, x2)
    u = cs.SX.sym("u")
    xdot = cs.vertcat((1 - x2**2) * x1 - x2 + u, x1)
    L = x1**2 + x2**2 + u**2
    return cs.Function("f", [x, u], [xdot, L], ["x", "u"], ["xdot", "L"])

# time and control horizon
T = 10.0
N = 20  # number of control intervals
h = T / N

# coefficients and dynamics and cost functions
d = 3
C, D, B = get_coeffs(d)
F = get_dynamics_and_cost()

# create nlp problem
nlp = Nlp[cs.SX]()

# create variables
nx, nu = 2, 1
X, _, _ = nlp.variable("x", (nx, N + 1), lb=[[-0.25], [-np.inf]])
XC, _, _ = nlp.variable("x_colloc", (nx, N * d), lb=[[-0.25], [-np.inf]])
U, _, _ = nlp.variable("u", (nu, N), lb=-1, ub=0.85)

# create initial state and perturbation parameter
x0 = nlp.parameter("x0", (nx, 1))
nlp.constraint("init", X[:, 0], "==", x0)
p = nlp.parameter("p", (nx, 1))
x0_ = cs.DM([[0], [1]])
p_ = cs.DM([[0], [0]])

# formulate nlp with collocation
J = 0.0
X_ = cs2array(X).T
XC_ = cs2array(XC).reshape((nx, N, d)).transpose((1, 0, 2))
U_ = cs2array(U).T
for k, (x, x_next, xc, u) in enumerate(zip(X_[:-1], X_[1:], XC_, U_)):
    # convert back to symbolic
    x = array2cs(x)
    x_next = array2cs(x_next)
    xc = array2cs(xc)
    u = array2cs(u)

    # perturb first state with p
    if k == 0:
        x += p

    # propagate collocation points and compute associated cost
    f_k, q_k = F(xc, u)

    # create collocation constraints
    xp = x @ C[0, 1:] + xc @ C[1:, 1:]
    nlp.constraint(f"colloc_{k}", h * f_k, "==", xp)

    # Add contribution to quadrature function
    J += h * (q_k @ B[1:])

    # create end state and constraint
    x_k_end = D[0] * x + xc @ D[1:]
    nlp.constraint(f"colloc_end_{k}", x_next, "==", x_k_end)

# set objective and solver
nlp.minimize(J)
nlp.init_solver({"print_time": False, "ipopt": {"print_level": 0, "sb": "yes"}})

# solve nlp
sol = nlp.solve(pars={"x0": x0_, "p": p_})

# compute sensitivity of solution w.r.t. p via wrapper (allows to use IPOPT)
t0 = time.perf_counter()
nlp_ = wrappers.NlpSensitivity(nlp, target_parameters=p)
dfdp, d2fdp2 = nlp_.parametric_sensitivity(nlp.f, solution=sol, second_order=True)
t1 = time.perf_counter() - t0
assert d2fdp2 is not None

# high-level approach, native to CasADi
prob = {"f": nlp.f, "x": nlp.x, "g": nlp.g, "p": nlp.p}
opts = {
    "qpsol": "qrqp",
    "qpsol_options": {"print_iter": False, "error_on_fail": False},
    "print_time": False,
}
solver = cs.nlpsol("solver", "sqpmethod", prob, opts)
sol_ = solver(x0=0, lbx=nlp.lbx, ubx=nlp.ubx, lbg=0, ubg=0, p=cs.vertcat(x0_, p_))

t2 = time.perf_counter()
jsolver = solver.factory("j", solver.name_in(), ["jac:f:p"])
hsolver = solver.factory("h", solver.name_in(), ["hess:f:p:p"])
kwargs = dict(
    x0=sol_["x"],
    lam_x0=sol_["lam_x"],
    lam_g0=sol_["lam_g"],
    lbx=nlp.lbx,
    ubx=nlp.ubx,
    lbg=0,
    ubg=0,
    p=cs.vertcat(x0_, p_),
)
jsol = jsolver(**kwargs)
hsol = hsolver(**kwargs)
t3 = time.perf_counter() - t2

# compare results
dfdp = dfdp.full().squeeze()
d2fdp2 = d2fdp2.full().squeeze()
print("My Jacobian of f w.r.t. p:")
print(dfdp)
print("\nMy Hessian of f w.r.t. p:")
print(d2fdp2)

jac_f_p = jsol["jac_f_p"].full().squeeze()[2:]
hess_f_p_p = hsol["hess_f_p_p"].full()[2:, 2:]
i_lower = np.tril_indices(hess_f_p_p.shape[0], -1)
hess_f_p_p[i_lower] = hess_f_p_p.T[i_lower]
print("\nJacobian of f w.r.t. p:")
print(jac_f_p)
print("\nHessian of f w.r.t. p:")
print(hess_f_p_p)

print("\nComparison:")
print(np.abs(jac_f_p.T - dfdp))
print("\nHessian of f w.r.t. p:")
print(np.abs(hess_f_p_p - d2fdp2))
print("\nDurations (mine vs native):", t1, "vs", t3)

# plot result
t = np.linspace(0, T, N + 1)
x_opt = sol.vals["x"].full()
u_opt = sol.vals["u"].full()
plt.figure()
plt.plot(t, x_opt[0], "--")
plt.plot(t, x_opt[1], "-")
plt.step(t[:-1], u_opt[0], "-.")
plt.xlabel("t")
plt.legend(["x1", "x2", "u"])
plt.grid()
plt.show()


import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import time
import restthru

host = 'http://127.0.0.1:4950'
restthru.http_init()
distances = '/group/laserpose'

tamCel = 50
numCelX = 80
numCelY = 80

precisao = 50
passo = 1*np.pi/180

K_sigma_array = np.array([[[0.5],[[2,0],[0,0.2]]],[[0.02],[[0.5,0],[0,0.05]]],[[0.0002],[[0.05,0],[0,0.005]]]])
Pmin = 0.4

x = np.linspace(0, numCelX, numCelX)
y = np.linspace(0, numCelY, numCelY)
xx, yy = np.meshgrid(x, y)

def sensing():
    res,_ = restthru.http_get(host+distances)

    px = res[1]["pose"]["x"]
    py = res[1]["pose"]["y"]
    pth = res[1]["pose"]["th"]*np.pi/180
    dist = np.asarray(res[0]["distances"])
    fi = np.linspace(pth - np.pi/2, pth + np.pi/2, 181)
    for index,value in enumerate(fi):
        if value > np.pi:
            fi[index] = (fi[index]-2*np.pi)
        elif value < - np.pi:
            fi[index] = (fi[index]+2*np.pi)
    fi = np.asarray(fi)
    mu_array = np.vstack((dist, fi)).T
    return px, py, pth, mu_array

for K, sigma in K_sigma_array:
    mapa = np.zeros([numCelX,numCelY])
    z = np.zeros([len(x),len(y)])
    maximo = 0

    fig = plt.figure(figsize=(18, 16))
    graph = 0
    start = time.time()

    invSigma = np.linalg.inv(sigma)

    print("K = ",K[0])
    print("sigma =", sigma)

    while(graph < 4):
        px, py, pth, mu_array = sensing()
        for i in range(len(x)):
            xi = (i-1)*tamCel+tamCel/2
            for j in range(len(y)):
                yj = (j-1)*tamCel + tamCel/2
                r = np.sqrt((xi-px)**2+(yj-py)**2)
                angCel = np.arctan2((yj-py),(xi-px))
                b = angCel - pth
                if b > np.pi:
                    b = (b-2*np.pi)
                elif b < - np.pi:
                    b = (b+2*np.pi)
                if abs(b) <= np.pi/2:
                    for mu in mu_array:
                        delta = np.array([r, angCel]) - mu
                        if abs(delta[1])>2*passo:
                            continue
                        if r < mu[0]:
                            P = Pmin
                        else:
                            P = 0.5
                        delta[0]  = delta[0]/1000
                        z[j][i] = P + (K/(2*np.pi*np.dot(sigma[0][0],sigma[1][1])) + 0.5 - P)*np.exp(-0.5 * (np.dot(np.dot(delta,invSigma),delta.T)))
                        mapa[j][i] = mapa[j][i] + np.log(z[j][i]/(1-z[j][i]))
                        if z[j][i] > maximo:
                            maximo = z[j][i]
        cycle = time.time()
        diff = int(cycle-start)

        if diff > 30:
            start = time.time()
            graph += 1
            ax = fig.add_subplot(2, 2, graph, projection='3d')
            ax.plot_surface(xx,yy,mapa, cmap=cm.coolwarm, linewidth=0, antialiased=False)
            ax.view_init(azim=-45, elev=45)
    print("z máximo", maximo)
    fig.savefig(str(K[0]) + ".png")


# Run all experiments

from train_single_models import train_and_evaluate
from run_prediction import run_compositors, print_predictors
from plotting import create_cd_diagram, create_cd_best_overall, create_single_prediction_files, create_cd_diagram_compositors

if __name__ == '__main__':

    # Single models
    #train_and_evaluate(None)

    # Compositors
    override = False
    debug = False
    dry_run = False
    run_compositors(None, override=override, noparallel=debug, dry_run=dry_run)

    # Results
    create_cd_diagram_compositors()

    # Export
    create_single_prediction_files()


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

from django.core.management.base import BaseCommand

from main.models import TournamentGroup, TournamentRound, Venue, Team, Game, Extra, ExtraChoice

class Command(BaseCommand):
    help = 'Creates the real WWC 2023 data'

    TOURNAMENT_START = '2023-07-20 19:00:00+12'

    def handle(self, *args, **options):
        self.clear_data()
        self.venues = self.create_venues()
        self.groups = self.create_groups()
        self.rounds = self.create_rounds()
        self.teams = self.create_teams()
        self.create_first_round_games()
        self.create_extra_bets()

    def clear_data(self):
        Game.objects.all().delete()
        Extra.objects.all().delete()
        ExtraChoice.objects.all().delete()
        TournamentRound.objects.all().delete()
        TournamentGroup.objects.all().delete()
        Team.objects.all().delete()
        Venue.objects.all().delete()

    def create_venues(self):
        venues = {
            'sydney_big': Venue(city='Sydney', name='Stadium Australia', capacity=83500),
            'sydney_small': Venue(city='Sydney', name='Sydney Football Stadium', capacity=42512),
            'brisbane': Venue(city='Brisbane', name='Lang Park', capacity=52263),
            'melbourne': Venue(city='Melbourne', name='Melbourne Rectangular Stadium', capacity=30052),
            'perth': Venue(city='Perth', name='Perth Rectangular Stadium', capacity=22225),
            'adelaide': Venue(city='Adelaide', name='Hindmarsh Stadium', capacity=18435),
            'auckland': Venue(city='Auckland', name='Eden Park', capacity=48276),
            'wellington': Venue(city='Wellington', name='Wellington Regional Stadium', capacity=39000),
            'dunedin': Venue(city='Dunedin', name='Forsyth Barr Stadium', capacity=28744),
            'hamilton': Venue(city='Hamilton', name='Waikato Stadium', capacity=25111),
        }

        for key, venue in venues.items():
            venue.save()
        return venues

    def create_groups(self):
        groups = {
            'a': TournamentGroup(name='Gruppe A', abbreviation='A'),
            'b': TournamentGroup(name='Gruppe B', abbreviation='B'),
            'c': TournamentGroup(name='Gruppe C', abbreviation='C'),
            'd': TournamentGroup(name='Gruppe D', abbreviation='D'),
            'e': TournamentGroup(name='Gruppe E', abbreviation='E'),
            'f': TournamentGroup(name='Gruppe F', abbreviation='F'),
            'g': TournamentGroup(name='Gruppe G', abbreviation='G'),
            'h': TournamentGroup(name='Gruppe H', abbreviation='H'),
        }

        for key, group in groups.items():
            group.save()
        return groups

    def create_rounds(self):
        rounds = {
            'vorrunde': TournamentRound(name='Vorrunde', is_knock_out=False, display_order='010', abbreviation='VOR'),
            'achtel': TournamentRound(name='Achtelfinale', is_knock_out=True, display_order='020', abbreviation='AF'),
            'viertel': TournamentRound(name='Viertelfinale', is_knock_out=True, display_order='030', abbreviation='VF'),
            'halb': TournamentRound(name='Halbfinale', is_knock_out=True, display_order='040', abbreviation='HF'),
            'platz3': TournamentRound(name='Spiel um Platz 3', is_knock_out=True, display_order='050', abbreviation='SP3'),
            'finale': TournamentRound(name='Finale', is_knock_out=True, display_order='060', abbreviation='FIN'),
        }

        for key, round in rounds.items():
            round.save()
        return rounds

    # Country codes according to official FIFA code list
    # See https://de.wikipedia.org/wiki/FIFA-L%C3%A4ndercode
    def create_teams(self):
        teams = {
            'NZL': Team(name='Neuseeland', abbreviation='NZL', group=self.groups['a']),
            'NOR': Team(name='Norwegen', abbreviation='NOR', group=self.groups['a']),
            'PHI': Team(name='Philippinen', abbreviation='PHI', group=self.groups['a']),
            'SUI': Team(name='Schweiz', abbreviation='SUI', group=self.groups['a']),

            'AUS': Team(name='Australien', abbreviation='AUS', group=self.groups['b']),
            'IRL': Team(name='Irland', abbreviation='IRL', group=self.groups['b']),
            'CAN': Team(name='Kanada', abbreviation='CAN', group=self.groups['b']),
            'NGA': Team(name='Nigeria', abbreviation='NGA', group=self.groups['b']),

            'CRC': Team(name='Costa Rica', abbreviation='CRC', group=self.groups['c']),
            'JPN': Team(name='Japan', abbreviation='JPN', group=self.groups['c']),
            'ZAM': Team(name='Sambia', abbreviation='ZAM', group=self.groups['c']),
            'ESP': Team(name='Spanien', abbreviation='ESP', group=self.groups['c']),

            'CHN': Team(name='China', abbreviation='CHN', group=self.groups['d']),
            'DEN': Team(name='Dänemark', abbreviation='DEN', group=self.groups['d']),
            'ENG': Team(name='England', abbreviation='ENG', group=self.groups['d']),
            'HAI': Team(name='Haiti', abbreviation='HAI', group=self.groups['d']),

            'USA': Team(name='USA', abbreviation='USA', group=self.groups['e']),
            'VIE': Team(name='Vietnam', abbreviation='VIE', group=self.groups['e']),
            'NED': Team(name='Niederlande', abbreviation='NED', group=self.groups['e']),
            'POR': Team(name='Portugal', abbreviation='POR', group=self.groups['e']),

            'FRA': Team(name='Frankreich', abbreviation='FRA', group=self.groups['f']),
            'JAM': Team(name='Jamaika', abbreviation='JAM', group=self.groups['f']),
            'BRA': Team(name='Brasilien', abbreviation='BRA', group=self.groups['f']),
            'PAN': Team(name='Panama', abbreviation='PAN', group=self.groups['f']),

            'SWE': Team(name='Schweden', abbreviation='SWE', group=self.groups['g']),
            'RSA': Team(name='Südafrika', abbreviation='KSA', group=self.groups['g']),
            'ITA': Team(name='Italien', abbreviation='ITA', group=self.groups['g']),
            'ARG': Team(name='Argentinien', abbreviation='ARG', group=self.groups['g']),

            'GER': Team(name='Deutschland', abbreviation='GER', group=self.groups['h']),
            'MAR': Team(name='Marokko', abbreviation='MAR', group=self.groups['h']),
            'COL': Team(name='Kolumbien', abbreviation='COL', group=self.groups['h']),
            'KOR': Team(name='Südkorea', abbreviation='KOR', group=self.groups['h']),
        }

        for key, team in teams.items():
            team.save()
        return teams

    def create_first_round_games(self):
        self.a_game('NZL', 'NOR', self.TOURNAMENT_START, 'auckland')
        self.a_game('PHI', 'SUI', '2023-07-21 17:00:00+12', 'dunedin')
        self.a_game('NZL', 'PHI', '2023-07-25 17:30:00+12', 'wellington')
        self.a_game('SUI', 'NOR', '2023-07-25 20:00:00+12', 'hamilton')
        self.a_game('SUI', 'NZL', '2023-07-30 19:00:00+12', 'dunedin')
        self.a_game('NOR', 'PHI', '2023-07-30 19:00:00+12', 'auckland')

        self.a_game('AUS', 'IRL', '2023-07-20 20:00:00+10', 'sydney_small')
        self.a_game('NGA', 'CAN', '2023-07-21 12:30:00+10', 'melbourne')
        self.a_game('CAN', 'IRL', '2023-07-26 20:00:00+08', 'perth')
        self.a_game('AUS', 'NGA', '2023-07-27 20:00:00+10', 'brisbane')
        self.a_game('CAN', 'AUS', '2023-07-31 20:00:00+10', 'melbourne')
        self.a_game('IRL', 'NGA', '2023-07-31 20:00:00+10', 'brisbane')

        self.a_game('ESP', 'CRC', '2023-07-21 19:30:00+12', 'wellington')
        self.a_game('ZAM', 'JPN', '2023-07-22 19:00:00+12', 'hamilton')
        self.a_game('JPN', 'CRC', '2023-07-26 17:00:00+12', 'dunedin')
        self.a_game('ESP', 'ZAM', '2023-07-26 19:30:00+12', 'auckland')
        self.a_game('JPN', 'ESP', '2023-07-31 19:00:00+12', 'wellington')
        self.a_game('CRC', 'ZAM', '2023-07-31 19:00:00+12', 'hamilton')

        self.a_game('ENG', 'HAI', '2023-07-22 19:30:00+10', 'brisbane')
        self.a_game('DEN', 'CHN', '2023-07-22 20:00:00+08', 'perth')
        self.a_game('ENG', 'DEN', '2023-07-28 18:30:00+10', 'sydney_small')
        self.a_game('CHN', 'HAI', '2023-07-28 20:30:00+09:30', 'adelaide')
        self.a_game('CHN', 'ENG', '2023-08-01 20:30:00+09:30', 'adelaide')
        self.a_game('HAI', 'DEN', '2023-08-01 19:00:00+08', 'perth')

        self.a_game('USA', 'VIE', '2023-07-22 13:00:00+12', 'auckland')
        self.a_game('NED', 'POR', '2023-07-23 19:30:00+12', 'dunedin')
        self.a_game('USA', 'NED', '2023-07-27 13:00:00+12', 'wellington')
        self.a_game('POR', 'VIE', '2023-07-27 19:30:00+12', 'hamilton')
        self.a_game('POR', 'USA', '2023-08-01 19:00:00+12', 'auckland')
        self.a_game('VIE', 'NED', '2023-08-01 19:00:00+12', 'dunedin')

        self.a_game('FRA', 'JAM', '2023-07-23 20:00:00+10', 'sydney_small')
        self.a_game('BRA', 'PAN', '2023-07-24 20:30:00+09:30', 'adelaide')
        self.a_game('FRA', 'BRA', '2023-07-29 20:00:00+10', 'brisbane')
        self.a_game('PAN', 'JAM', '2023-07-29 20:30:00+08', 'perth')
        self.a_game('PAN', 'FRA', '2023-08-02 20:00:00+10', 'sydney_small')
        self.a_game('JAM', 'BRA', '2023-08-02 20:00:00+10', 'melbourne')

        self.a_game('SWE', 'RSA', '2023-07-23 17:00:00+12', 'wellington')
        self.a_game('ITA', 'ARG', '2023-07-24 18:00:00+12', 'auckland')
        self.a_game('ARG', 'RSA', '2023-07-28 12:00:00+12', 'dunedin')
        self.a_game('SWE', 'ITA', '2023-07-29 19:30:00+12', 'wellington')
        self.a_game('ARG', 'SWE', '2023-08-02 19:00:00+12', 'hamilton')
        self.a_game('RSA', 'ITA', '2023-08-02 19:00:00+12', 'wellington')

        self.a_game('GER', 'MAR', '2023-07-24 18:30:00+10', 'melbourne')
        self.a_game('COL', 'KOR', '2023-07-25 12:00:00+10', 'sydney_small')
        self.a_game('KOR', 'MAR', '2023-07-30 14:00:00+09:30', 'adelaide')
        self.a_game('GER', 'COL', '2023-07-30 19:30:00+10', 'sydney_small')
        self.a_game('KOR', 'GER', '2023-08-03 20:00:00+10', 'brisbane')
        self.a_game('MAR', 'COL', '2023-08-03 18:00:00+08', 'perth')

    def create_extra_bets(self):
        winner = Extra(name='Wer wird Weltmeister?', points=5, deadline=self.TOURNAMENT_START)
        deu = Extra(name='Wie weit kommt Deutschland?', points=5, deadline=self.TOURNAMENT_START)
        winner.save()
        deu.save()

        for team in Team.objects.all():
            ExtraChoice(name=team.name, extra=winner, sort_index=team.name[0:9]).save()

        ExtraChoice(name='Vorrunde', extra=deu, sort_index='010').save()
        ExtraChoice(name='Achtelfinale', extra=deu, sort_index='020').save()
        ExtraChoice(name='Viertelfinale', extra=deu, sort_index='030').save()
        ExtraChoice(name='Vierter', extra=deu, sort_index='040').save()
        ExtraChoice(name='Dritter', extra=deu, sort_index='050').save()
        ExtraChoice(name='Zweiter', extra=deu, sort_index='060').save()
        ExtraChoice(name='Weltmeister', extra=deu, sort_index='070').save()

    def a_game(self, home, away, kickoff, venue, deadline=TOURNAMENT_START):
        hometeam = self.teams[home]
        awayteam = self.teams[away]
        Game(kickoff=kickoff, deadline=deadline, round=self.rounds['vorrunde'],
             hometeam=hometeam, awayteam=awayteam, venue=self.venues[venue]).save()


class Solution(object):
    def restoreString(self, s, indices):
        """
        :type s: str
        :type indices: List[int]
        :rtype: str
        """
        t = [""] * len(s)
        for i in range(len(s)):
            t[indices[i]] = s[i]
        return "".join(t)


import time
time_start = time.time()

# PCA with 510 components done! Time elapsed: 1.7129957675933838 seconds
# Cumulative variance explained by 510 principal components: 0.9470420452326141

pca_510 = PCA(n_components=510)
pca_result_510 = pca_510.fit_transform(np_fps)

time_elapsed = time.time()-time_start

txt = 'PCA with 510 components done! Time elapsed: {} seconds'
print(txt.format(time_elapsed))

txt = 'Cumulative variance explained by 510 principal components: {}'
print(txt.format(np.sum(pca_510.explained_variance_ratio_)))

# t-SNE done! Time elapsed: 111.94909977912903
time_start = time.time()

# The perplexity is related to the number of nearest neighbors that is
# used in other manifold learning algorithms.
# early_exaggeration float, optional (default: 12.0)
# Controls how tight natural clusters in the original space are
# in the embedded space and how much space will be between them.
# Other things to try
# pca_tsne = TSNE(learning_rate=50, perplexity=50, early_exaggeration = 20.0, method = 'exact', n_components=3).fit_transform(pca_result_300)
# pca_tsne = TSNE(learning_rate=300, perplexity=50, early_exaggeration = 15.0, method = 'exact', n_components=3).fit_transform(pca_result_300)

pca_tsne = TSNE(learning_rate = 200, n_components=2).fit_transform(pca_result_510)
txt = 't-SNE done! Time elapsed: {} '
print(txt.format(time.time()-time_start))

xs = pca_tsne[:,0]
ys = pca_tsne[:,1]

plt.scatter(xs, ys, c = ys_fit, alpha = 0.5);


import sys
input = lambda: sys.stdin.readline().rstrip()

def resolve():
    R, C = map(int, input().split())
    a = [list(map(int, input().split())) for _ in range(R)]

    ans = 0
    for i in range(2**R):
        sum = 0
        for c in range(C):
            front = 0
            for r in range(R):
                if a[r][c] != (i>>r)&1:
                    front += 1
            sum += max(front, R-front)
        ans = max(sum, ans)

    print(ans)

if __name__ == '__main__':
    resolve()