import os
from PyQt5 import QtCore, QtGui, QtWidgets
from .presenter import MainWindowPresenter, MessageReplyType
from .dock_manager import DockManager
from .scene_manager import SceneManager
from sscanss.config import settings, path_for, DOCS_URL, __version__
from sscanss.ui.dialogs import (ProgressDialog, ProjectDialog, Preferences, AlignmentErrorDialog,
                                SampleExportDialog, ScriptExportDialog, PathLengthPlotter, AboutDialog)
from sscanss.ui.widgets import GLWidget, StatusBar, FileDialog
from sscanss.core.scene import Node
from sscanss.core.util import (Primitives, Directions, TransformType, PointType, MessageSeverity, Attributes,
                               toggleActionInGroup)

MAIN_WINDOW_TITLE = 'SScanSS 2'

class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()

        self.recent_projects = []
        self.presenter = MainWindowPresenter(self)

        self.undo_stack = QtWidgets.QUndoStack(self)
        self.undo_view = QtWidgets.QUndoView(self.undo_stack)
        self.undo_view.setWindowTitle('History')
        self.undo_view.setAttribute(QtCore.Qt.WA_QuitOnClose, False)

        self.gl_widget = GLWidget(self)
        self.setCentralWidget(self.gl_widget)

        self.docks = DockManager(self)
        self.scenes = SceneManager(self)
        self.progress_dialog = ProgressDialog(self)
        self.about_dialog = AboutDialog(self)
        self.updater = Updater(self)

        self.createActions()
        self.createMenus()
        self.createToolBar()
        self.createStatusBar()

        self.setWindowTitle(MAIN_WINDOW_TITLE)
        self.setWindowIcon(QtGui.QIcon(path_for('logo.png')))
        self.setMinimumSize(1024, 900)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        self.readSettings()
        self.updateMenus()

    def createActions(self):
        self.new_project_action = QtWidgets.QAction('&New Project', self)
        self.new_project_action.setStatusTip('Create a new project')
        self.new_project_action.setIcon(QtGui.QIcon(path_for('file.png')))
        self.new_project_action.setShortcut(QtGui.QKeySequence.New)
        self.new_project_action.triggered.connect(self.showNewProjectDialog)

        self.open_project_action = QtWidgets.QAction('&Open Project', self)
        self.open_project_action.setStatusTip('Open an existing project')
        self.open_project_action.setIcon(QtGui.QIcon(path_for('folder-open.png')))
        self.open_project_action.setShortcut(QtGui.QKeySequence.Open)
        self.open_project_action.triggered.connect(self.openProject)

        self.save_project_action = QtWidgets.QAction('&Save Project', self)
        self.save_project_action.setStatusTip('Save project')
        self.save_project_action.setIcon(QtGui.QIcon(path_for('save.png')))
        self.save_project_action.setShortcut(QtGui.QKeySequence.Save)
        self.save_project_action.triggered.connect(lambda: self.presenter.saveProject())

        self.save_as_action = QtWidgets.QAction('Save &As...', self)
        self.save_as_action.setShortcut(QtGui.QKeySequence.SaveAs)
        self.save_as_action.triggered.connect(lambda: self.presenter.saveProject(save_as=True))

        self.export_samples_action = QtWidgets.QAction('Samples', self)
        self.export_samples_action.setStatusTip('Export samples')
        self.export_samples_action.triggered.connect(self.presenter.exportSamples)

        self.export_fiducials_action = QtWidgets.QAction('Fiducial Points', self)
        self.export_fiducials_action.setStatusTip('Export fiducial points')
        self.export_fiducials_action.triggered.connect(lambda: self.presenter.exportPoints(PointType.Fiducial))

        self.export_measurements_action = QtWidgets.QAction('Measurement Points', self)
        self.export_measurements_action.setStatusTip('Export measurement points')
        self.export_measurements_action.triggered.connect(lambda: self.presenter.exportPoints(PointType.Measurement))

        self.export_vectors_action = QtWidgets.QAction('Measurement Vectors', self)
        self.export_vectors_action.setStatusTip('Export measurement vectors')
        self.export_vectors_action.triggered.connect(self.presenter.exportVectors)

        self.export_alignment_action = QtWidgets.QAction('Alignment Matrix', self)
        self.export_alignment_action.setStatusTip('Export alignment matrix')
        self.export_alignment_action.triggered.connect(self.presenter.exportAlignmentMatrix)

        self.export_script_action = QtWidgets.QAction('Script', self)
        self.export_script_action.setStatusTip('Export script')
        self.export_script_action.triggered.connect(self.showScriptExport)

        self.exit_action = QtWidgets.QAction('E&xit', self)
        self.exit_action.setStatusTip(f'Quit {MAIN_WINDOW_TITLE}')
        self.exit_action.setShortcut(QtGui.QKeySequence.Quit)
        self.exit_action.triggered.connect(self.close)

        # Edit Menu Actions
        self.undo_action = self.undo_stack.createUndoAction(self, '&Undo')
        self.undo_action.setStatusTip('Undo the last action')
        self.undo_action.setIcon(QtGui.QIcon(path_for('undo.png')))
        self.undo_action.setShortcut(QtGui.QKeySequence.Undo)

        self.redo_action = self.undo_stack.createRedoAction(self, '&Redo')
        self.redo_action.setStatusTip('Redo the last undone action')
        self.redo_action.setIcon(QtGui.QIcon(path_for('redo.png')))
        self.redo_action.setShortcut(QtGui.QKeySequence.Redo)

        self.undo_view_action = QtWidgets.QAction('Undo &History', self)
        self.undo_view_action.setStatusTip('View undo history')
        self.undo_view_action.triggered.connect(self.showUndoHistory)

        self.preferences_action = QtWidgets.QAction('Preferences', self)
        self.preferences_action.setStatusTip('Change application preferences')
        self.preferences_action.triggered.connect(lambda: self.showPreferences(None))
        self.preferences_action.setShortcut(QtGui.QKeySequence('Ctrl+Shift+P'))

        # View Menu Actions
        self.solid_render_action = QtWidgets.QAction(Node.RenderMode.Solid.value, self)
        self.solid_render_action.setStatusTip('Render sample as solid object')
        self.solid_render_action.setIcon(QtGui.QIcon(path_for('solid.png')))
        self.solid_render_action.triggered.connect(lambda: self.scenes.changeRenderMode(Node.RenderMode.Solid))
        self.solid_render_action.setCheckable(True)

        self.line_render_action = QtWidgets.QAction(Node.RenderMode.Wireframe.value, self)
        self.line_render_action.setStatusTip('Render sample as wireframe object')
        self.line_render_action.setIcon(QtGui.QIcon(path_for('wireframe.png')))
        self.line_render_action.triggered.connect(lambda: self.scenes.changeRenderMode(Node.RenderMode.Wireframe))
        self.line_render_action.setCheckable(True)

        self.blend_render_action = QtWidgets.QAction(Node.RenderMode.Transparent.value, self)
        self.blend_render_action.setStatusTip('Render sample as transparent object')
        self.blend_render_action.setIcon(QtGui.QIcon(path_for('blend.png')))
        self.blend_render_action.triggered.connect(lambda: self.scenes.changeRenderMode(Node.RenderMode.Transparent))
        self.blend_render_action.setCheckable(True)
        self.blend_render_action.setChecked(True)

        self.render_action_group = QtWidgets.QActionGroup(self)
        self.render_action_group.addAction(self.solid_render_action)
        self.render_action_group.addAction(self.line_render_action)
        self.render_action_group.addAction(self.blend_render_action)

        self.show_bounding_box_action = QtWidgets.QAction('Toggle Bounding Box', self)
        self.show_bounding_box_action.setStatusTip('Toggle sample bounding box')
        self.show_bounding_box_action.setIcon(QtGui.QIcon(path_for('boundingbox.png')))
        self.show_bounding_box_action.setCheckable(True)
        self.show_bounding_box_action.setChecked(self.gl_widget.show_bounding_box)
        self.show_bounding_box_action.toggled.connect(self.gl_widget.showBoundingBox)

        self.show_coordinate_frame_action = QtWidgets.QAction('Toggle Coordinate Frame', self)
        self.show_coordinate_frame_action.setStatusTip('Toggle scene coordinate frame')
        self.show_coordinate_frame_action.setIcon(QtGui.QIcon(path_for('hide_coordinate_frame.png')))
        self.show_coordinate_frame_action.setCheckable(True)
        self.show_coordinate_frame_action.setChecked(self.gl_widget.show_coordinate_frame)
        self.show_coordinate_frame_action.toggled.connect(self.gl_widget.showCoordinateFrame)

        self.show_fiducials_action = QtWidgets.QAction('Toggle Fiducial Points', self)
        self.show_fiducials_action.setStatusTip('Show or hide fiducial points')
        self.show_fiducials_action.setIcon(QtGui.QIcon(path_for('hide_fiducials.png')))
        self.show_fiducials_action.setCheckable(True)
        self.show_fiducials_action.setChecked(True)
        action = self.scenes.toggleVisibility
        self.show_fiducials_action.toggled.connect(lambda state, a=Attributes.Fiducials: action(a, state))

        self.show_measurement_action = QtWidgets.QAction('Toggle Measurement Points', self)
        self.show_measurement_action.setStatusTip('Show or hide measurement points')
        self.show_measurement_action.setIcon(QtGui.QIcon(path_for('hide_measurement.png')))
        self.show_measurement_action.setCheckable(True)
        self.show_measurement_action.setChecked(True)
        self.show_measurement_action.toggled.connect(lambda state, a=Attributes.Measurements: action(a, state))

        self.show_vectors_action = QtWidgets.QAction('Toggle Measurement Vectors', self)
        self.show_vectors_action.setStatusTip('Show or hide measurement vectors')
        self.show_vectors_action.setIcon(QtGui.QIcon(path_for('hide_vectors.png')))
        self.show_vectors_action.setCheckable(True)
        self.show_vectors_action.setChecked(True)
        self.show_vectors_action.toggled.connect(lambda state, a=Attributes.Vectors: action(a, state))

        self.reset_camera_action = QtWidgets.QAction('Reset View', self)
        self.reset_camera_action.setStatusTip('Reset camera view')
        self.reset_camera_action.triggered.connect(self.gl_widget.resetCamera)
        self.reset_camera_action.setShortcut(QtGui.QKeySequence('Ctrl+0'))

        self.sample_manager_action = QtWidgets.QAction('Samples', self)
        self.sample_manager_action.setStatusTip('Open sample manager')
        self.sample_manager_action.triggered.connect(self.docks.showSampleManager)
        self.sample_manager_action.setShortcut(QtGui.QKeySequence('Ctrl+Shift+A'))

        self.fiducial_manager_action = QtWidgets.QAction('Fiducial Points', self)
        self.fiducial_manager_action.setStatusTip('Open fiducial point manager')
        self.fiducial_manager_action.triggered.connect(lambda: self.docks.showPointManager(PointType.Fiducial))
        self.fiducial_manager_action.setShortcut(QtGui.QKeySequence('Ctrl+Shift+F'))

        self.measurement_manager_action = QtWidgets.QAction('Measurements Points', self)
        self.measurement_manager_action.setStatusTip('Open measurement point manager')
        self.measurement_manager_action.triggered.connect(lambda: self.docks.showPointManager(PointType.Measurement))
        self.measurement_manager_action.setShortcut(QtGui.QKeySequence('Ctrl+Shift+M'))

        self.vector_manager_action = QtWidgets.QAction('Measurements Vectors', self)
        self.vector_manager_action.setStatusTip('Open measurement vector manager')
        self.vector_manager_action.triggered.connect(self.docks.showVectorManager)
        self.vector_manager_action.setShortcut(QtGui.QKeySequence('Ctrl+Shift+V'))

        self.simulation_dialog_action = QtWidgets.QAction('Simulation Results', self)
        self.simulation_dialog_action.setStatusTip('Open simulation dialog')
        self.simulation_dialog_action.triggered.connect(self.docks.showSimulationResults)
        self.simulation_dialog_action.setShortcut(QtGui.QKeySequence('Ctrl+Shift+L'))

        # Insert Menu Actions
        self.import_sample_action = QtWidgets.QAction('File...', self)
        self.import_sample_action.setStatusTip('Import sample from 3D model file')
        self.import_sample_action.triggered.connect(self.presenter.importSample)

        self.import_fiducial_action = QtWidgets.QAction('File...', self)
        self.import_fiducial_action.setStatusTip('Import fiducial points from file')
        self.import_fiducial_action.triggered.connect(lambda: self.presenter.importPoints(PointType.Fiducial))

        self.keyin_fiducial_action = QtWidgets.QAction('Key-in', self)
        self.keyin_fiducial_action.setStatusTip('Input X,Y,Z values of a fiducial point')
        self.keyin_fiducial_action.triggered.connect(lambda: self.docks.showInsertPointDialog(PointType.Fiducial))

        self.import_measurement_action = QtWidgets.QAction('File...', self)
        self.import_measurement_action.setStatusTip('Import measurement points from file')
        self.import_measurement_action.triggered.connect(lambda: self.presenter.importPoints(PointType.Measurement))

        self.keyin_measurement_action = QtWidgets.QAction('Key-in', self)
        self.keyin_measurement_action.setStatusTip('Input X,Y,Z values of a measurement point')
        self.keyin_measurement_action.triggered.connect(lambda: self.docks.showInsertPointDialog(PointType.Measurement))

        self.pick_measurement_action = QtWidgets.QAction('Graphical Selection', self)
        self.pick_measurement_action.setStatusTip('Select measurement points on a cross-section of sample')
        self.pick_measurement_action.triggered.connect(self.docks.showPickPointDialog)

        self.import_measurement_vector_action = QtWidgets.QAction('File...', self)
        self.import_measurement_vector_action.setStatusTip('Import measurement vectors from file')
        self.import_measurement_vector_action.triggered.connect(self.presenter.importVectors)

        self.select_strain_component_action = QtWidgets.QAction('Select Strain Component', self)
        self.select_strain_component_action.setStatusTip('Specify measurement vector direction')
        self.select_strain_component_action.triggered.connect(self.docks.showInsertVectorDialog)

        self.align_via_pose_action = QtWidgets.QAction('6D Pose', self)
        self.align_via_pose_action.setStatusTip('Specify position and orientation of sample on instrument')
        self.align_via_pose_action.triggered.connect(self.docks.showAlignSample)

        self.align_via_matrix_action = QtWidgets.QAction('Transformation Matrix', self)
        self.align_via_matrix_action.triggered.connect(self.presenter.alignSampleWithMatrix)
        self.align_via_matrix_action.setStatusTip('Align sample on instrument with transformation matrix')

        self.align_via_fiducials_action = QtWidgets.QAction('Fiducials Points', self)
        self.align_via_fiducials_action.triggered.connect(self.presenter.alignSampleWithFiducialPoints)
        self.align_via_fiducials_action.setStatusTip('Align sample on instrument using measured fiducial points')

        self.run_simulation_action = QtWidgets.QAction('&Run Simulation', self)
        self.run_simulation_action.setStatusTip('Start new simulation')
        self.run_simulation_action.setShortcut('F5')
        self.run_simulation_action.setIcon(QtGui.QIcon(path_for('play.png')))
        self.run_simulation_action.triggered.connect(self.presenter.runSimulation)

        self.stop_simulation_action = QtWidgets.QAction('&Stop Simulation', self)
        self.stop_simulation_action.setStatusTip('Stop active simulation')
        self.stop_simulation_action.setShortcut('Shift+F5')
        self.stop_simulation_action.setIcon(QtGui.QIcon(path_for('stop.png')))
        self.stop_simulation_action.triggered.connect(self.presenter.stopSimulation)

        self.compute_path_length_action = QtWidgets.QAction('Calculate Path Length', self)
        self.compute_path_length_action.setStatusTip('Enable path length calculation in simulation')
        self.compute_path_length_action.setCheckable(True)
        self.compute_path_length_action.setChecked(False)

        self.check_limits_action = QtWidgets.QAction('Hardware Limits Check', self)
        self.check_limits_action.setStatusTip('Enable positioning system joint limit checks in simulation')
        self.check_limits_action.setCheckable(True)
        self.check_limits_action.setChecked(True)

        self.show_sim_graphics_action = QtWidgets.QAction('Show Graphically', self)
        self.show_sim_graphics_action.setStatusTip('Enable graphics rendering in simulation')
        self.show_sim_graphics_action.setCheckable(True)
        self.show_sim_graphics_action.setChecked(True)

        self.check_collision_action = QtWidgets.QAction('Collision Detection', self)
        self.check_collision_action.setStatusTip('Enable collision detection in simulation')
        self.check_collision_action.setCheckable(True)
        self.check_collision_action.setChecked(False)

        self.show_sim_options_action = QtWidgets.QAction('Simulation Options', self)
        self.show_sim_options_action.setStatusTip('Change simulation settings')
        self.show_sim_options_action.triggered.connect(lambda: self.showPreferences(settings.Group.Simulation))

        # Instrument Actions
        self.positioning_system_action = QtWidgets.QAction('Positioning System', self)
        self.positioning_system_action.setStatusTip('Change positioning system settings')
        self.positioning_system_action.triggered.connect(self.docks.showPositionerControl)

        self.jaw_action = QtWidgets.QAction('Incident Jaws', self)
        self.jaw_action.setStatusTip('Change incident jaws settings')
        self.jaw_action.triggered.connect(self.docks.showJawControl)

        # Help Actions
        self.show_documentation_action = QtWidgets.QAction('&Documentation', self)
        self.show_documentation_action.setStatusTip('Show online documentation')
        self.show_documentation_action.setShortcut('F1')
        self.show_documentation_action.setIcon(QtGui.QIcon(path_for('question.png')))
        self.show_documentation_action.triggered.connect(self.showDocumentation)

        self.check_update_action = QtWidgets.QAction(f'&Check for Update', self)
        self.check_update_action.setStatusTip('Check the internet for software updates')
        self.check_update_action.triggered.connect(lambda: self.updater.check())

        self.show_about_action = QtWidgets.QAction(f'&About {MAIN_WINDOW_TITLE}', self)
        self.show_about_action.setStatusTip(f'About {MAIN_WINDOW_TITLE}')
        self.show_about_action.triggered.connect(self.about_dialog.show)

        # ToolBar Actions
        self.rotate_sample_action = QtWidgets.QAction('Rotate Sample', self)
        self.rotate_sample_action.setStatusTip('Rotate sample around fixed coordinate frame axis')
        self.rotate_sample_action.setIcon(QtGui.QIcon(path_for('rotate.png')))
        self.rotate_sample_action.triggered.connect(lambda: self.docks.showTransformDialog(TransformType.Rotate))

        self.translate_sample_action = QtWidgets.QAction('Translate Sample', self)
        self.translate_sample_action.setStatusTip('Translate sample along fixed coordinate frame axis')
        self.translate_sample_action.setIcon(QtGui.QIcon(path_for('translate.png')))
        self.translate_sample_action.triggered.connect(lambda: self.docks.showTransformDialog(TransformType.Translate))

        self.transform_sample_action = QtWidgets.QAction('Transform Sample with Matrix', self)
        self.transform_sample_action.setStatusTip('Transform sample with transformation matrix')
        self.transform_sample_action.setIcon(QtGui.QIcon(path_for('transform-matrix.png')))
        self.transform_sample_action.triggered.connect(lambda: self.docks.showTransformDialog(TransformType.Custom))

        self.move_origin_action = QtWidgets.QAction('Move Origin to Sample', self)
        self.move_origin_action.setStatusTip('Translate sample using bounding box')
        self.move_origin_action.setIcon(QtGui.QIcon(path_for('origin.png')))
        self.move_origin_action.triggered.connect(lambda: self.docks.showTransformDialog(TransformType.Origin))

        self.plane_align_action = QtWidgets.QAction('Rotate Sample by Plane Alignment', self)
        self.plane_align_action.setStatusTip('Rotate sample using a selected plane')
        self.plane_align_action.setIcon(QtGui.QIcon(path_for('plane_align.png')))
        self.plane_align_action.triggered.connect(lambda: self.docks.showTransformDialog(TransformType.Plane))

        self.toggle_scene_action = QtWidgets.QAction('Toggle Scene', self)
        self.toggle_scene_action.setStatusTip('Toggle between sample and instrument scene')
        self.toggle_scene_action.setIcon(QtGui.QIcon(path_for('exchange.png')))
        self.toggle_scene_action.triggered.connect(self.scenes.toggleScene)
        self.toggle_scene_action.setShortcut(QtGui.QKeySequence('Ctrl+T'))

    def createMenus(self):
        main_menu = self.menuBar()
        main_menu.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)

        file_menu = main_menu.addMenu('&File')
        file_menu.addAction(self.new_project_action)
        file_menu.addAction(self.open_project_action)
        self.recent_menu = file_menu.addMenu('Open &Recent')
        file_menu.addAction(self.save_project_action)
        file_menu.addAction(self.save_as_action)
        file_menu.addSeparator()
        self.export_menu = file_menu.addMenu('Export...')
        self.export_menu.addAction(self.export_script_action)
        self.export_menu.addSeparator()
        self.export_menu.addAction(self.export_samples_action)
        self.export_menu.addAction(self.export_fiducials_action)
        self.export_menu.addAction(self.export_measurements_action)
        self.export_menu.addAction(self.export_vectors_action)
        self.export_menu.addAction(self.export_alignment_action)
        file_menu.addSeparator()
        file_menu.addAction(self.exit_action)
        file_menu.aboutToShow.connect(self.populateRecentMenu)

        edit_menu = main_menu.addMenu('&Edit')
        edit_menu.addAction(self.undo_action)
        edit_menu.addAction(self.redo_action)
        edit_menu.addAction(self.undo_view_action)
        edit_menu.addSeparator()
        edit_menu.addAction(self.preferences_action)

        view_menu = main_menu.addMenu('&View')
        view_menu.addAction(self.solid_render_action)
        view_menu.addAction(self.line_render_action)
        view_menu.addAction(self.blend_render_action)
        view_menu.addSeparator()
        self.view_from_menu = view_menu.addMenu('View From')
        for index, direction in enumerate(Directions):
            view_from_action = QtWidgets.QAction(direction.value, self)
            view_from_action.setStatusTip(f'View scene from the {direction.value} axis')
            view_from_action.setShortcut(QtGui.QKeySequence(f'Ctrl+{index+1}'))
            action = self.gl_widget.viewFrom
            view_from_action.triggered.connect(lambda ignore, d=direction: action(d))
            self.view_from_menu.addAction(view_from_action)

        view_menu.addAction(self.reset_camera_action)
        view_menu.addSeparator()
        view_menu.addAction(self.show_bounding_box_action)
        view_menu.addAction(self.show_fiducials_action)
        view_menu.addAction(self.show_measurement_action)
        view_menu.addAction(self.show_vectors_action)
        view_menu.addAction(self.show_coordinate_frame_action)
        view_menu.addSeparator()
        self.other_windows_menu = view_menu.addMenu('Other Windows')
        self.other_windows_menu.addAction(self.sample_manager_action)
        self.other_windows_menu.addAction(self.fiducial_manager_action)
        self.other_windows_menu.addAction(self.measurement_manager_action)
        self.other_windows_menu.addAction(self.vector_manager_action)
        self.other_windows_menu.addAction(self.simulation_dialog_action)

        insert_menu = main_menu.addMenu('&Insert')
        sample_menu = insert_menu.addMenu('Sample')
        sample_menu.addAction(self.import_sample_action)
        self.primitives_menu = sample_menu.addMenu('Primitives')

        for primitive in Primitives:
            add_primitive_action = QtWidgets.QAction(primitive.value, self)
            add_primitive_action.setStatusTip(f'Add {primitive.value} model as sample')
            add_primitive_action.triggered.connect(lambda ignore, p=primitive: self.docks.showInsertPrimitiveDialog(p))
            self.primitives_menu.addAction(add_primitive_action)

        fiducial_points_menu = insert_menu.addMenu('Fiducial Points')
        fiducial_points_menu.addAction(self.import_fiducial_action)
        fiducial_points_menu.addAction(self.keyin_fiducial_action)

        measurement_points_menu = insert_menu.addMenu('Measurement Points')
        measurement_points_menu.addAction(self.import_measurement_action)
        measurement_points_menu.addAction(self.keyin_measurement_action)
        measurement_points_menu.addAction(self.pick_measurement_action)

        measurement_vectors_menu = insert_menu.addMenu('Measurement Vectors')
        measurement_vectors_menu.addAction(self.import_measurement_vector_action)
        measurement_vectors_menu.addAction(self.select_strain_component_action)

        self.instrument_menu = main_menu.addMenu('I&nstrument')
        self.change_instrument_menu = self.instrument_menu.addMenu('Change Instrument')
        self.updateChangeInstrumentMenu()

        self.align_sample_menu = self.instrument_menu.addMenu('Align Sample on Instrument')
        self.align_sample_menu.addAction(self.align_via_pose_action)
        self.align_sample_menu.addAction(self.align_via_matrix_action)
        self.align_sample_menu.addAction(self.align_via_fiducials_action)
        self.collimator_action_groups = {}

        simulation_menu = main_menu.addMenu('&Simulation')
        simulation_menu.addAction(self.run_simulation_action)
        simulation_menu.addAction(self.stop_simulation_action)
        simulation_menu.addSeparator()
        simulation_menu.addAction(self.check_limits_action)
        simulation_menu.addAction(self.show_sim_graphics_action)
        simulation_menu.addAction(self.compute_path_length_action)
        simulation_menu.addAction(self.check_collision_action)
        simulation_menu.addSeparator()
        simulation_menu.addAction(self.show_sim_options_action)

        help_menu = main_menu.addMenu('&Help')
        help_menu.addAction(self.show_documentation_action)
        help_menu.addSeparator()
        help_menu.addAction(self.check_update_action)
        help_menu.addAction(self.show_about_action)

    def updateMenus(self):
        enable = False if self.presenter.model.project_data is None else True

        self.save_project_action.setEnabled(enable)
        self.save_as_action.setEnabled(enable)
        for action in self.export_menu.actions():
            action.setEnabled(enable)

        self.render_action_group.setEnabled(enable)

        for action in self.view_from_menu.actions():
            action.setEnabled(enable)
        self.reset_camera_action.setEnabled(enable)
        self.show_bounding_box_action.setEnabled(enable)
        self.show_coordinate_frame_action.setEnabled(enable)
        self.show_fiducials_action.setEnabled(enable)
        self.show_measurement_action.setEnabled(enable)
        self.show_vectors_action.setEnabled(enable)

        for action in self.other_windows_menu.actions():
            action.setEnabled(enable)

        self.import_sample_action.setEnabled(enable)
        for action in self.primitives_menu.actions():
            action.setEnabled(enable)

        self.import_fiducial_action.setEnabled(enable)
        self.keyin_fiducial_action.setEnabled(enable)

        self.import_measurement_action.setEnabled(enable)
        self.keyin_measurement_action.setEnabled(enable)
        self.pick_measurement_action.setEnabled(enable)

        self.import_measurement_vector_action.setEnabled(enable)
        self.select_strain_component_action.setEnabled(enable)

        self.instrument_menu.setEnabled(enable)

        self.run_simulation_action.setEnabled(enable)
        self.stop_simulation_action.setEnabled(enable)
        self.check_limits_action.setEnabled(enable)
        self.show_sim_graphics_action.setEnabled(enable)
        self.compute_path_length_action.setEnabled(enable)
        self.check_collision_action.setEnabled(enable)

        self.rotate_sample_action.setEnabled(enable)
        self.translate_sample_action.setEnabled(enable)
        self.transform_sample_action.setEnabled(enable)
        self.move_origin_action.setEnabled(enable)
        self.plane_align_action.setEnabled(enable)
        self.toggle_scene_action.setEnabled(enable)

    def createToolBar(self):
        toolbar = self.addToolBar('ToolBar')
        toolbar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
        toolbar.setMovable(False)

        toolbar.addAction(self.new_project_action)
        toolbar.addAction(self.open_project_action)
        toolbar.addAction(self.save_project_action)
        toolbar.addAction(self.undo_action)
        toolbar.addAction(self.redo_action)
        toolbar.addSeparator()
        toolbar.addAction(self.solid_render_action)
        toolbar.addAction(self.line_render_action)
        toolbar.addAction(self.blend_render_action)
        toolbar.addAction(self.show_bounding_box_action)

        sub_button = QtWidgets.QToolButton(self)
        sub_button.setIcon(QtGui.QIcon(path_for('eye-slash.png')))
        sub_button.setPopupMode(QtWidgets.QToolButton.InstantPopup)
        sub_button.setToolTip('Show/Hide Elements')
        sub_button.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
        sub_button.addAction(self.show_fiducials_action)
        sub_button.addAction(self.show_measurement_action)
        sub_button.addAction(self.show_vectors_action)
        sub_button.addAction(self.show_coordinate_frame_action)
        toolbar.addWidget(sub_button)

        sub_button = QtWidgets.QToolButton(self)
        sub_button.setIcon(QtGui.QIcon(path_for('camera.png')))
        sub_button.setPopupMode(QtWidgets.QToolButton.InstantPopup)
        sub_button.setToolTip('Preset Views')
        sub_button.setMenu(self.view_from_menu)
        toolbar.addWidget(sub_button)

        toolbar.addSeparator()
        toolbar.addAction(self.rotate_sample_action)
        toolbar.addAction(self.translate_sample_action)
        toolbar.addAction(self.transform_sample_action)
        toolbar.addAction(self.move_origin_action)
        toolbar.addAction(self.plane_align_action)
        toolbar.addSeparator()
        toolbar.addAction(self.toggle_scene_action)

    def createStatusBar(self):
        sb = StatusBar()
        self.setStatusBar(sb)
        self.instrument_label = QtWidgets.QLabel()
        self.instrument_label.setAlignment(QtCore.Qt.AlignCenter)
        self.instrument_label.setToolTip('Current Instrument')
        sb.addPermanentWidget(self.instrument_label, alignment=QtCore.Qt.AlignLeft)

        self.cursor_label = QtWidgets.QLabel()
        self.cursor_label.setAlignment(QtCore.Qt.AlignCenter)
        sb.addPermanentWidget(self.cursor_label)

    @property
    def selected_render_mode(self):
        return Node.RenderMode(self.render_action_group.checkedAction().text())

    def readSettings(self):
        """ Loads window geometry from INI file """
        self.restoreGeometry(settings.value(settings.Key.Geometry))
        self.recent_projects = settings.value(settings.Key.Recent_Projects)

    def populateRecentMenu(self):
        self.recent_menu.clear()
        if self.recent_projects:
            for project in self.recent_projects:
                recent_project_action = QtWidgets.QAction(project, self)
                recent_project_action.triggered.connect(lambda ignore, p=project: self.openProject(p))
                self.recent_menu.addAction(recent_project_action)
        else:
            recent_project_action = QtWidgets.QAction('None', self)
            self.recent_menu.addAction(recent_project_action)

    def closeEvent(self, event):
        if self.presenter.confirmSave():
            settings.system.setValue(settings.Key.Geometry.value, self.saveGeometry())
            if self.recent_projects:
                settings.system.setValue(settings.Key.Recent_Projects.value, self.recent_projects)
            event.accept()
        else:
            event.ignore()

    def resetInstrumentMenu(self):
        self.instrument_menu.clear()
        self.instrument_menu.addMenu(self.change_instrument_menu)
        self.instrument_menu.addSeparator()
        self.instrument_menu.addAction(self.jaw_action)
        self.instrument_menu.addAction(self.positioning_system_action)
        self.instrument_menu.addSeparator()
        self.instrument_menu.addMenu(self.align_sample_menu)
        self.collimator_action_groups = {}

    def updateChangeInstrumentMenu(self):
        self.change_instrument_menu.clear()
        self.change_instrument_action_group = QtWidgets.QActionGroup(self)
        self.project_file_instrument_action = QtWidgets.QAction('', self)
        self.change_instrument_action_group.addAction(self.project_file_instrument_action)
        self.change_instrument_menu.addAction(self.project_file_instrument_action)
        self.project_file_instrument_separator = self.change_instrument_menu.addSeparator()
        self.project_file_instrument_action.setCheckable(True)
        self.project_file_instrument_action.setVisible(False)
        self.project_file_instrument_separator.setVisible(False)
        for name in sorted(self.presenter.model.instruments.keys()):
            change_instrument_action = QtWidgets.QAction(name, self)
            change_instrument_action.setStatusTip(f'Change instrument to {name}')
            change_instrument_action.setCheckable(True)
            change_instrument_action.triggered.connect(lambda ignore, n=name: self.presenter.changeInstrument(n))
            self.change_instrument_action_group.addAction(change_instrument_action)
            self.change_instrument_menu.addAction(change_instrument_action)
        self.toggleActiveInstrument()

    def toggleActiveInstrument(self):
        model = self.presenter.model
        if model.project_data is None or model.instrument is None:
            return

        self.instrument_label.setText(model.instrument.name)
        if model.checkInstrumentVersion():
            toggleActionInGroup(model.instrument.name, self.change_instrument_action_group)
            self.project_file_instrument_action.setVisible(False)
            self.project_file_instrument_separator.setVisible(False)
        else:
            self.project_file_instrument_action.setText(f'{model.instrument.name} (Project)')
            self.project_file_instrument_action.setChecked(True)
            self.project_file_instrument_action.setVisible(True)
            self.project_file_instrument_separator.setVisible(True)

    def addCollimatorMenu(self, detector, collimators, active, menu='Detector', show_more_settings=False):
        collimator_menu = QtWidgets.QMenu(menu, self)
        self.instrument_menu.insertMenu(self.jaw_action, collimator_menu)
        action_group = QtWidgets.QActionGroup(self)
        for name in collimators:
            change_collimator_action = self.__createChangeCollimatorAction(name, active, detector)
            collimator_menu.addAction(change_collimator_action)
            action_group.addAction(change_collimator_action)

        change_collimator_action = self.__createChangeCollimatorAction('None', str(active), detector)
        collimator_menu.addAction(change_collimator_action)
        action_group.addAction(change_collimator_action)
        self.collimator_action_groups[detector] = action_group
        if show_more_settings:
            collimator_menu.addSeparator()
            other_settings_action = QtWidgets.QAction('Other Settings', self)
            other_settings_action.setStatusTip('Change detector position settings')
            other_settings_action.triggered.connect(lambda ignore, d=detector: self.docks.showDetectorControl(d))
            collimator_menu.addAction(other_settings_action)

    def __createChangeCollimatorAction(self, name, active, detector):
        change_collimator_action = QtWidgets.QAction(name, self)
        change_collimator_action.setStatusTip(f'Change collimator to {name}')
        change_collimator_action.setCheckable(True)
        change_collimator_action.setChecked(active == name)
        change_collimator_action.triggered.connect(lambda ignore,
                                                          n=detector,
                                                          t=name: self.presenter.changeCollimators(n, t))

        return change_collimator_action

    def showUndoHistory(self):
        """ shows Undo History"""
        self.undo_view = QtWidgets.QUndoView(self.undo_stack)
        self.undo_view.setWindowTitle('Undo History')
        self.undo_view.show()
        self.undo_view.setAttribute(QtCore.Qt.WA_QuitOnClose, False)

    def showNewProjectDialog(self):
        if self.presenter.confirmSave():
            self.project_dialog = ProjectDialog(self.recent_projects, parent=self)
            self.project_dialog.setModal(True)
            self.project_dialog.show()

    def showPreferences(self, group=None):
        self.preferences = Preferences(self)
        self.preferences.setActiveGroup(group)
        self.preferences.setModal(True)
        self.preferences.show()

    def showAlignmentError(self):
        self.alignment_error = AlignmentErrorDialog(parent=self)
        self.alignment_error.setModal(True)
        self.alignment_error.show()

    def showPathLength(self):
        simulation = self.presenter.model.simulation
        if simulation is None:
            return

        if not simulation.compute_path_length:
            self.showMessage('Path Length computation is not enabled for this simulation.\n'
                             'Go to "Simulation > Compute Path Length" to enable it then \nrestart simulation.',
                             MessageSeverity.Information)
            return

        self.path_length_plotter = PathLengthPlotter(self)
        self.path_length_plotter.setModal(True)
        self.path_length_plotter.show()

    def showSampleExport(self, sample_list):
        sample_export = SampleExportDialog(sample_list, parent=self)
        if sample_export.exec() != QtWidgets.QFileDialog.Accepted:
            return ''

        return sample_export.selected

    def showScriptExport(self):
        simulation = self.presenter.model.simulation
        if simulation is None:
            self.showMessage('There are no simulation results to write in script.', MessageSeverity.Information)
            return

        if simulation.isRunning():
            self.showMessage('Finish or Stop the current simulation before attempting to write script.',
                             MessageSeverity.Information)
            return

        if not simulation.results:
            self.showMessage('There are no simulation results to write in script.', MessageSeverity.Information)
            return

        script_export = ScriptExportDialog(simulation, parent=self)
        script_export.setModal(True)
        script_export.show()

    def showProjectName(self):
        project_name = self.presenter.model.project_data['name']
        save_path = self.presenter.model.save_path
        if save_path:
            title = f'{project_name} [{save_path}] - {MAIN_WINDOW_TITLE}'
        else:
            title = f'{project_name} - {MAIN_WINDOW_TITLE}'
        self.setWindowTitle(title)

    def showSaveDialog(self, filters, current_dir='', title=''):
        directory = current_dir if current_dir else os.path.splitext(self.presenter.model.save_path)[0]
        filename = FileDialog.getSaveFileName(self, title,  directory, filters)
        return filename

    def showOpenDialog(self, filters, current_dir='', title=''):
        directory = current_dir if current_dir else os.path.dirname(self.presenter.model.save_path)
        filename = FileDialog.getOpenFileName(self, title, directory, filters)
        return filename

    def showMessage(self, message, severity=MessageSeverity.Critical):
        """
        Shows an message with a given severity.

        :param message: Error message
        :type message: str
        :param severity: severity of the message
        :type severity: MessageSeverity
        """
        if severity == MessageSeverity.Critical:
            QtWidgets.QMessageBox.critical(self, MAIN_WINDOW_TITLE, message)
        elif severity == MessageSeverity.Warning:
            QtWidgets.QMessageBox.warning(self, MAIN_WINDOW_TITLE, message)
        else:
            QtWidgets.QMessageBox.information(self, MAIN_WINDOW_TITLE, message)

    def showSaveDiscardMessage(self, name):
        """
        Shows an message to confirm if unsaved changes should be saved.

        :param name: the name of the unsaved project
        """
        message = 'The document has been modified.\n\n' \
                  'Do you want to save changes to "{}"?\t'.format(name)
        buttons = QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Discard | QtWidgets.QMessageBox.Cancel
        reply = QtWidgets.QMessageBox.warning(self,
                                              MAIN_WINDOW_TITLE,
                                              message, buttons,
                                              QtWidgets.QMessageBox.Cancel)

        if reply == QtWidgets.QMessageBox.Save:
            return MessageReplyType.Save
        if reply == QtWidgets.QMessageBox.Discard:
            return MessageReplyType.Discard
        else:
            return MessageReplyType.Cancel

    def showSelectChoiceMessage(self, message, choices, default_choice=0):
        message_box = QtWidgets.QMessageBox(self)
        message_box.setWindowTitle(MAIN_WINDOW_TITLE)
        message_box.setText(message)

        buttons = []
        for choice in choices:
            buttons.append(QtWidgets.QPushButton(choice))
            message_box.addButton(buttons[-1], QtWidgets.QMessageBox.YesRole)

        message_box.setDefaultButton(buttons[default_choice])
        message_box.exec()

        for index, button in enumerate(buttons):
            if message_box.clickedButton() == button:
                return choices[index]

    def openProject(self, filename=''):
        """
        This function loads a project with the given filename. if filename is empty,
        a file dialog will be opened.

        :param filename: full path of file
        :type filename: str
        """
        if not self.presenter.confirmSave():
            return

        if not filename:
            filename = self.showOpenDialog('hdf5 File (*.h5)', title='Open Project',
                                           current_dir=self.presenter.model.save_path)
            if not filename:
                return

        self.presenter.useWorker(self.presenter.openProject, [filename], self.presenter.updateView,
                                 self.presenter.projectOpenError)

    def showDocumentation(self):
        """
        This function opens the documentation html in the system's default browser
        """
        import webbrowser
        webbrowser.open_new(DOCS_URL)

    def showUpdateMessage(self, message):
        """ Shows software update message in a custom dialog with a check-box to change
        the "check update on startup" setting.

        :param message: message
        :type message: string
        """
        message_box = QtWidgets.QMessageBox(self)
        message_box.setWindowTitle(f'{MAIN_WINDOW_TITLE} Update')
        message_box.setText(message)
        message_box.setTextFormat(QtCore.Qt.RichText)
        checkbox = QtWidgets.QCheckBox('Check for updates on startup')
        checkbox.setChecked(settings.value(settings.Key.Check_Update))
        checkbox.stateChanged.connect(lambda state: settings.system.setValue(settings.Key.Check_Update.value,
                                                                             state == QtCore.Qt.Checked))
        message_box.setCheckBox(checkbox)

        cancel_button = QtWidgets.QPushButton('Close')
        message_box.addButton(cancel_button, QtWidgets.QMessageBox.NoRole)

        message_box.exec()

class Updater:

    def __init__(self, parent):
        self.startup = False
        self.parent = parent

    def check(self, startup=False):
        """ Asynchronously checks for new release using the Github release API and notifies the user when
        update is found, not found or an error occurred. When startup is true, the user will
        only be notified if update is found.

        :param startup: flag that indicates the check is at startup
        :type startup: bool
        """
        if startup and not settings.value(settings.Key.Check_Update):
            return

        self.startup = startup
        if not startup:
            self.parent.progress_dialog.show('Checking the Internet for Updates')
        self.parent.presenter.useWorker(self.checkHelper, [], self.onSuccess, self.onFaiure,
                                        self.parent.progress_dialog.close)

    def checkHelper(self):
        import json
        import urllib.request

        response = urllib.request.urlopen('https://api.github.com/repos/ISISNeutronMuon/SScanSS-2/releases/latest')
        tag_name = json.loads(response.read()).get('tag_name')
        if not tag_name or tag_name.endswith(__version__):
            return False, __version__

        return True, tag_name

    def onSuccess(self, result):
        update_found, tag_name = result
        if update_found:
            self.parent.showUpdateMessage(f'A new version {tag_name} of {MAIN_WINDOW_TITLE} is available. Download the '
                                        'installer from <a href="https://github.com/ISISNeutronMuon/SScanSS-2/releases">'
                                        'https://github.com/ISISNeutronMuon/SScanSS-2/releases</a>.<br/><br/>')
        else:
            if self.startup:
                return
            self.showUpdateMessage(f'You are running the latest version of {MAIN_WINDOW_TITLE}.<br/><br/>')

    def onFaiure(self, exception):
        from urllib.error import URLError, HTTPError
        import logging

        logging.error('An error occurred while checking for updates', exc_info=exception)
        if self.startup:
            return

        if isinstance(exception,  HTTPError):
            self.parent.showUpdateMessage(f'You are running the latest version of {MAIN_WINDOW_TITLE}.<br/><br/>')
        elif isinstance(exception, URLError):
            self.parent.showMessage('An error occurred when attempting to connect to update server. '
                                    'Check your internet connection and/or firewall and try again.')


#!/usr/bin/python3
# Webex tkinter application
# author: r0thl3ss

from tkinter import *
import webbrowser
import pathlib
import os
import json

# All basic vars
current_folder = os.path.abspath(__file__).replace(__file__.split("\\")[-1], "")
with open(current_folder + "config.json", encoding="utf-8") as read_file:
    config = json.load(read_file)

book_color = config["book_color"]
webex_link = config["webex_link"]
books_folder = current_folder + config["books_folder"]
book_text = config["book_text"]

window = Tk()
window.title("Eclass")
window.geometry("677x307")

# Labels for days
row_days = 1
for i in config["days"]:
  Label(window, text=i).grid(column=0, row=row_days)
  row_days += 2

# Labels for time
column_time = 1
for i in config["time_table"]:
  Label(window, text=i).grid(column=column_time, row=0)
  column_time += 1

# Lessons labels & buttons loop
for i in config["lessons"]:
  lesson = i.split(",")
  Button(window, text=lesson[0],
      command=lambda lesson=lesson: webbrowser.open(webex_link + lesson[1]),
      height=1, width=11).grid(column=lesson[4], row=2*int(lesson[3])-1)
  if lesson[2]=="none":
    Button(window, text="---",height=1, width=11, fg=book_color).grid(column=lesson[4], row=2*int(lesson[3]))
  else:
    Button(window, text=book_text,
      command=lambda lesson=lesson: webbrowser.open(books_folder + "\\" + lesson[2]),
      height=1, width=11, fg=book_color).grid(column=lesson[4], row=2*int(lesson[3]))

# Extra loop
extra_count = 1
for i in config["extra"]:
  if extra_count > 8 :
    break
  extra_i = i.split(",")
  Button(window, text=extra_i[0],
      command=lambda extra_i=extra_i: webbrowser.open(extra_i[1]),
      height=1, width=11, fg=extra_i[2]).grid(column=extra_count, row=11)
  extra_count += 1

# Initiating
window.mainloop()


import turtle

def draw_square():
	window = turtle.Screen()
	window.bgcolor("black")

	spiral = turtle.Turtle()
	spiral.shape("turtle")
	spiral.color("white")
	for i in range(40):
		spiral.forward(i * 10)
		spiral.right(144)

	# sara = turtle.Turtle()
	# sara.shape("arrow")
	# sara.color("white")
	# sara.speed(3)
	# for i in range (0, 36):
	# 	count=0
	# 	while count<4:
	# 		sara.forward(100)
	# 		sara.right(90)
	# 		count+=1
	# 	sara.right(10)

	# besho = turtle.Turtle()
	# besho.shape("arrow")
	# besho.color("red")
	# besho.circle(100)

	# baby = turtle.Turtle()
	# baby.shape("arrow")
	# baby.color("green")
	# baby.forward(100)
	# baby.right(120)
	# baby.forward(100)
	# baby.right(120)
	# baby.forward(100)

	window.exitonclick()

draw_square()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division, print_function

import gzip
import cPickle as pickle
import numpy as np
# import pandas as pd
import matplotlib.pyplot as plt

import sklearn as sk
from sklearn.datasets import make_classification as mk
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import Imputer
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.cross_validation import cross_val_score

__author__ = 'Estrade Victor'

def add_2(X_mask, y_mask, n_X, n_y, features_importance=None):
    # Add n_y label
    idx = np.random.choice(np.where(y_mask == 0)[0], size=n_y, replace=False)
    y_mask[idx] = 1

    # Add n_X features
    # -> where there is a label (case 2)
    target = X_mask+(1-y_mask.reshape(-1, 1))
    where = np.where(target == 0)
    if features_importance is None:
        idx = np.random.choice(where[0].shape[0], size=n_X, replace=False)
    else:
        assert(features_importance.shape[0] == X_mask.shape[1])
        p = np.empty_like(where[1], dtype=np.float64)
        p[:] = features_importance[where[1][:]]
        p /= np.sum(p)
        idx = np.random.choice(where[0].shape[0], size=n_X, replace=False, p=p)
    X_mask[where[0][idx], where[1][idx]] = 1
    return X_mask, y_mask

def add_3(X_mask, y_mask, n_X, n_y, features_importance=None):
    # Add n_y label
    idx = np.random.choice(np.where(y_mask == 0)[0], size=n_y, replace=False)
    y_mask[idx] = 1

    # Add n_X features
    # -> anywhere (case 3)
    where = np.where(X_mask == 0)
    if features_importance is None:
        idx = np.random.choice(where[0].shape[0], size=n_X, replace=False)
    else:
        assert(features_importance.shape[0] == X_mask.shape[1])
        p = np.empty_like(where[1], dtype=np.float64)
        p[:] = features_importance[where[1][:]]
        p /= np.sum(p)
        idx = np.random.choice(where[0].shape[0], size=n_X, replace=False, p=p)
    X_mask[where[0][idx], where[1][idx]] = 1
    return X_mask, y_mask

def mask_data(X, mask):
    res = np.empty_like(X)
    res.fill(np.nan)
    res[np.where(mask)] = X[np.where(mask)]
    return res

def clip(X_mask, y_mask):
    s = np.sum(X_mask, 1)+y_mask
    idx = np.where(s != 0)[0]
    return idx

def work(c1, c2, c3, X, y, clf):
    X_mask = np.zeros_like(X, dtype=np.int64)
    y_mask = np.zeros_like(y, dtype=np.int64)
    n_y = y_mask.shape[0]/30
    n_X = X_mask.shape[1]/2*n_y
    p = np.arange(X.shape[1], dtype=np.float64)
    p = p/np.sum(p)
    X_mask, y_mask = add_2(X_mask, y_mask, n_X, n_y,
                               features_importance=p)
    print('n_X', n_X, 'n_y', n_y)
    costs = []
    i = 0
    while(np.sum(X_mask == 0) > n_X and np.sum(y_mask == 0) > n_y and i < 15):
        print('==================')
        print('Iteration', i)
        print('------------------')
        i += 1
        X_mask, y_mask = add_2(X_mask, y_mask, n_X, n_y,
                               features_importance=p)
        idx = clip(X_mask, y_mask)
        X_train = mask_data(X, X_mask)[idx, :]
        y_train = mask_data(y, y_mask)[idx]
        clf.fit(X_train, y_train)
        # acc = accuracy_score(y_train, clf.predict(X_train))
        acc = cross_val_score(clf, X_train, y_train, scoring='accuracy', cv=10)
        cost = c1*np.sum(X_mask) + c2*np.sum(y_mask) + c3 * 1-np.min(acc)
        costs.append(cost)
        print('error:', 1-np.min(acc))
        print('cost:', cost)
        print(X_train.shape[0], y_train.shape[0])
        # p = clf.named_steps['forest'].feature_importances_
        # print(p, p.shape)
        # print(X_train.shape)
    return costs

if __name__ == '__main__':
    print('I am at your service, master.')
    X, y = mk(n_samples=1500, n_features=15,
              n_informative=5, n_redundant=2, n_repeated=0, n_classes=2,
              n_clusters_per_class=1)

    # f = gzip.open('data/mnist.pkl.gz', 'rb')
    # train_S, valid_S, test_S = pickle.load(f)
    # f.close()
    # X, y = train_S

    clf = Pipeline([("imputer",
                    Imputer(missing_values=np.nan,
                            strategy="most_frequent",
                            axis=0)),
                    ("forest",
                     RandomForestClassifier(random_state=0,
                                            n_estimators=100))])
    costs = work(1, 5, 50*X.shape[0], X, y, clf)
    plt.plot(costs)
    plt.show()
    clf.fit(X, y)
    error = 1-cross_val_score(clf, X, y, scoring='accuracy', cv=10)
    print('error min:', np.mean(error), '+/-', np.std(error))


from flask import json

from flask.ext.admin import Admin, BaseView, expose
from flask.ext.admin.contrib.sqla import ModelView

from app import db
from helpers import json_alchemy_encoder
import models

__author__ = 'artem'

class GroupModelView(ModelView):
	column_labels = dict(name='Название')

class RoleModelView(ModelView):
	column_labels = dict(name='Название')

class UserModelView(ModelView):
	column_labels = dict(username='Имя пользователя', password='Пароль')

class CompanyModelView(ModelView):
	column_exclude_list = ['session_tokens']
	column_labels = dict(name='Название',
	                     ur_name='Юридическое название',
	                     ur_address='Юридический адрес',
	                     inn='ИНН',
	                     kpp='КПП',
	                     name_of_bank='Название банка',
	                     bik='БИК',
	                     payment_account='Счет для платажей',
	                     korr_account='Корреспондирующий счет',
	                     ogrn='ОГРН')

class RoleView(BaseView):
	@expose('/')
	def index(self):
		roles = models.Role.query.all()
		roles_json = json.dumps(roles, cls=json_alchemy_encoder(False), check_circular=False)
		return self.render('roles.html', json=roles_json)

def init_admin(app):
	admin = Admin(app, name='onega', template_mode='bootstrap3')
	admin.add_view(CompanyModelView(models.Company, db.session, name='Компании'))
	admin.add_view(GroupModelView(models.Group, db.session, name='Группы'))
	admin.add_view(UserModelView(models.User, db.session, name='Пользователи'))
	admin.add_view(RoleModelView(models.Role, db.session, name="Роли"))
	admin.add_view(RoleView(name='Роли Дерево', endpoint='role-tree'))


player1=input("what is your name?")
player2=input("what is your name?")
player1_answer = input("%s, do you want to choose rock, paper or scissors?" % player1)
player2_answer = input("%s, do you want to choose rock, paper or scissors?" % player2)

def compare(p1, p2):
    if p1 == p2:
        return("It's a tie!")
    elif p1 == 'rock':
        if p2 == 'scissors':
            return("Rock wins!")
        else:
            return("Paper wins!")
    elif p1 == 'scissors':
        if p2 == 'paper':
            return("Scissors win!")
        else:
            return("Rock wins!")
    elif p1 == 'paper':
        if p2 == 'rock':
            return("Paper wins!")
        else:
            return("Scissors win!")
    else:
        return("Invalid input! You have not entered rock, paper or scissors, try again.")
        sys.exit()

print(compare(player1_answer, player2_answer))


import random

import tensorflow

from keras.utils import Sequence
import numpy as np
from keras_preprocessing.image import ImageDataGenerator

class Sequencer(Sequence):
    def __init__(self, X, y, batch_size, sequence_size, data_gen_args):
        """A `Sequence` implementation that can augment data
            X: The numpy array of inputs.
            y: The numpy array of targets.
            batch_size: The generator mini-batch size.
            sequence_size: The number of elements in the sequence
            data_gen_args: The arguments for the ImageDataGenerator to apply on X, y
        """

        self.X = X
        self.y = y
        self.batch_size = batch_size
        self.sequence_encoding = random.sample(range(0, sequence_size), sequence_size)
        self.imgaug = ImageDataGenerator(data_gen_args)

    def __len__(self):
        return len(self.sequence_encoding) // self.batch_size

    def on_epoch_end(self):
        pass

    def __getitem__(self, batch_idx):
        batch_X = np.zeros((self.batch_size, self.X.shape[1], self.X.shape[2], self.X.shape[3]))
        batch_y = np.zeros((self.batch_size, self.y.shape[1], self.y.shape[2], self.y.shape[3]))

        for i in range(self.batch_size):
            cur_real_idx = (batch_idx + i) % self.X.shape[0]
            # This creates a dictionary with the params
            params = self.imgaug.get_random_transform(batch_X[i].shape,
                                                      seed=self.sequence_encoding[batch_idx * self.batch_size + i])
            # We can now deterministicly augment all the images
            batch_X[i] = self.imgaug.apply_transform(self.X[cur_real_idx], params)
            batch_y[i] = self.imgaug.apply_transform(self.y[cur_real_idx], params)

        return batch_X, batch_y


"""
The 'polly' Experiment
====================

This experiment applies polly's transformations to all projects and measures
the runtime.

This forms the baseline numbers for the other experiments.

Measurements
------------

3 Metrics are generated during this experiment:
    time.user_s - The time spent in user space in seconds (aka virtual time)
    time.system_s - The time spent in kernel space in seconds (aka system time)
    time.real_s - The time spent overall in seconds (aka Wall clock)
"""

from benchbuild.experiment import RuntimeExperiment
from benchbuild.experiments.raw import run_with_time
from benchbuild.utils.actions import (Prepare, Build, Download, Configure,
                                      Clean, MakeBuildDir, Run, Echo)
from benchbuild.settings import CFG
import functools
import warnings
import copy
import uuid
import re

class ShouldNotBeNone(RuntimeWarning):
    """User warning, if config var is null."""

class PollyPerformance(RuntimeExperiment):
    """ The polly performance experiment. """

    NAME = "pollyperformance"

    def actions_for_project(self, project):
        configs = CFG["perf"]["config"].value()
        if configs is None:
            warnings.warn("({0}) should not be null.".format(
                repr(CFG["perf"]["config"])),
                          category=ShouldNotBeNone, stacklevel=2)
            return

        config_list = re.split(r'\s*', configs)

        config_with_llvm = []
        for config in config_list:
            config_with_llvm.append("-mllvm")
            config_with_llvm.append(config)

        project.cflags = ["-O3", "-fno-omit-frame-pointer",
                          "-Xclang", "-load",
                          "-Xclang", "LLVMPolyJIT.so",
                          "-mllvm", "-polly"] + config_with_llvm

        actns = []
        jobs = CFG["jobs"].value()
        for i in range(1, int(jobs)):
            cp = copy.deepcopy(project)
            cp.run_uuid = uuid.uuid4()

            cp.cflags += ["-mllvm", "-polly-num-threads={0}".format(i)]
            cp.runtime_extension = functools.partial(
                run_with_time, cp, self, CFG, i)

            actns.extend([
                MakeBuildDir(cp),
                Echo("{0} core configuration. Configure & Compile".format(i)),
                Prepare(cp),
                Download(cp),
                Configure(cp),
                Build(cp),
                Echo("{0} core configuration. Run".format(i)),
                Run(cp),
                Clean(cp)
            ])
        return actns


import sys

sys.path.append("../../../")

from dan.lib.helper import *

import math
import random

from solid import *
from solid.utils import *

parts = []

SEGMENTS = 12

class Wemos:
    width = 25.6
    length = 34.4
    depth = 0.9

    header_y_offset = 7
    header_thickness = 2.45
    header_height = 9.5
    header_length = 20.9

    hole_radius = 1.05

    hole_offset = 3.2
    hole_back_offset = 3.5

    def render(self):
        base = cube([self.width, self.length, self.depth])

        header = cube([self.header_thickness, self.header_length, self.header_height])
        header_left = translate([0, self.header_y_offset, self.depth])(header)
        header_right = translate(
            [self.width - self.header_thickness, self.header_y_offset, self.depth]
        )(header)

        screw_hole = down(0.5)(
            cylinder(r=self.hole_radius, h=self.depth + 1, segments=SEGMENTS)
        )

        screw_hole_a = translate(
            [self.hole_offset, self.length - self.hole_back_offset, 0]
        )(screw_hole)
        screw_hole_b = translate([self.width - self.hole_offset, self.hole_offset, 0])(
            screw_hole
        )

        return union()(base, header_left, header_right) - (screw_hole_a + screw_hole_b)

class WemosOLEDShield:
    width = Wemos.width
    length = 29.6
    depth = Wemos.depth

    bottom_header_offset = 2.6
    screen_height = 3.1

    screen_y_offset = 14
    screen_x_offset = 5
    screen_y_size = 13
    screen_x_size = width - (screen_x_offset * 2)

    def render(self):
        base = cube([self.width, self.length, self.depth])

        return base

height_to_screen = (
    Wemos.depth
    + Wemos.header_height
    + WemosOLEDShield.bottom_header_offset
    + WemosOLEDShield.depth
    + WemosOLEDShield.screen_height
)

class Case:
    floor_thickness = 3
    wall_thickness = 3
    top_thickness = 3
    board_margin = 1
    board_z_offset = 7

    wall_height = board_z_offset + height_to_screen + 3

    width = Wemos.width + board_margin * 2 + wall_thickness * 2
    length = Wemos.length + board_margin * 2 + wall_thickness * 2

    usb_hole_height = 12
    usb_hole_width = 14

    usb_hole_z_offset = 4

    button_y_offset = wall_thickness + board_margin + 3.5
    button_z_offset = (
        board_z_offset
        + Wemos.depth
        + Wemos.header_height
        + WemosOLEDShield.bottom_header_offset
        - 2
    )
    button_stem_width = 3
    button_stem_thickness = 2.5
    button_top_rad = 2

    button_gap = 0.8
    button_gap_shape = rotate(a=90, v=[0, 1, 0])(
        cylinder(h=wall_thickness + 1, r=button_gap, segments=SEGMENTS)
    )

    button_gap_z_start = floor_thickness + board_z_offset
    button_gap_prevent = translate([-5, -5, 0])(cube([20, 20, button_gap_z_start]))

    screw_hole_rad = 0.7
    screw_hole_base_size = board_margin + 6

    def render(self):
        def wall(w, l, h, r):
            r = r * 0.9999999
            return minkowski()(
                translate([r, r, r])(cube([w - r * 2, l - r * 2, h - r * 2])),
                sphere(r=r, segments=SEGMENTS),
            )

        base = wall(
            self.width, self.length, self.floor_thickness, self.floor_thickness * 0.5
        )

        usb_hole = translate(
            [
                self.width * 0.5 - (self.usb_hole_width * 0.5),
                -0.5,
                self.floor_thickness + self.usb_hole_z_offset,
            ]
        )(cube([self.usb_hole_width, self.wall_thickness + 1, self.usb_hole_height]))

        front_wall = (
            wall(
                self.width,
                self.wall_thickness,
                self.floor_thickness + self.wall_height,
                self.wall_thickness * 0.5,
            )
            - usb_hole
        )
        back_wall = forward(self.length - self.wall_thickness)(
            wall(
                self.width,
                self.wall_thickness,
                self.floor_thickness + self.wall_height,
                self.wall_thickness * 0.5,
            )
        )

        side_wall = wall(
            self.wall_thickness,
            self.length,
            self.floor_thickness + self.wall_height,
            self.wall_thickness * 0.5,
        )

        button_shape = right((self.wall_thickness - self.button_stem_thickness) * 0.5)(
            cube(
                [
                    self.button_stem_thickness,
                    self.button_stem_width,
                    self.button_z_offset,
                ]
            )
        )
        button_shape += translate(
            [0, self.button_stem_width * 0.5, self.button_z_offset]
        )(
            scale([0.75, 1.03, 1.03])(
                rotate(a=90, v=[0, 1, 0])(
                    sphere(r=self.button_top_rad, segments=SEGMENTS)
                )
            ),
            right(self.wall_thickness)(
                scale([1, 1.03, 1.03])(
                    rotate(a=90, v=[0, 1, 0])(
                        sphere(r=self.button_top_rad, segments=SEGMENTS)
                    )
                )
            ),
            rotate(a=90, v=[0, 1, 0])(
                cylinder(
                    r=self.button_top_rad, h=self.wall_thickness, segments=SEGMENTS
                )
            ),
        )

        button_shape = up(self.floor_thickness)(button_shape)

        side_wall -= translate(
            [-1, self.button_y_offset - self.button_stem_width * 0.5, 0]
        )(minkowski()(button_shape, self.button_gap_shape) - self.button_gap_prevent)

        side_wall += translate(
            [0, self.button_y_offset - self.button_stem_width * 0.5, 0]
        )(button_shape)

        def screw_hole_base(hole=True):
            screw_hole_base = cube(
                [
                    self.screw_hole_base_size,
                    self.screw_hole_base_size,
                    self.board_z_offset + Wemos.depth,
                ]
            )
            if hole:
                screw_hole_base -= translate(
                    [
                        self.board_margin + Wemos.hole_offset,
                        self.board_margin + Wemos.hole_offset,
                        -1,
                    ]
                )(
                    cylinder(
                        r=self.screw_hole_rad,
                        h=self.board_z_offset + Wemos.depth + 2,
                        segments=SEGMENTS,
                    )
                )
            screw_hole_base -= translate(
                [
                    self.board_margin - 0.2,
                    self.board_margin - 0.2,
                    self.board_z_offset - 0.1,
                ]
            )(
                cube(
                    [
                        self.screw_hole_base_size,
                        self.screw_hole_base_size,
                        Wemos.depth + 1,
                    ]
                )
            )
            return screw_hole_base

        screw_hole_a = translate(
            [self.wall_thickness, self.wall_thickness, self.floor_thickness]
        )(screw_hole_base(False))
        screw_hole_b = translate(
            [
                self.width - self.wall_thickness,
                self.wall_thickness,
                self.floor_thickness,
            ]
        )(scale([-1, 1, 1])(screw_hole_base()))
        screw_hole_c = translate(
            [
                self.wall_thickness,
                self.length - self.wall_thickness,
                self.floor_thickness,
            ]
        )(scale([1, -1, 1])(screw_hole_base()))
        screw_hole_d = translate(
            [
                self.width - self.wall_thickness,
                self.length - self.wall_thickness,
                self.floor_thickness,
            ]
        )(scale([-1, -1, 1])(screw_hole_base(False)))

        top_inset = translate(
            [
                self.wall_thickness * 0.5,
                self.wall_thickness * 0.5,
                self.floor_thickness + self.wall_height - self.top_thickness,
            ]
        )(
            cube(
                [
                    self.width - self.wall_thickness,
                    self.length - self.wall_thickness,
                    self.top_thickness + 1,
                ]
            )
        )

        return (
            union()(
                base,
                front_wall,
                side_wall,
                translate([self.width, 0, 0])(scale([-1, 1, 1])(side_wall)),
                back_wall,
                screw_hole_a,
                screw_hole_b,
                screw_hole_c,
                screw_hole_d,
            )
            - top_inset
        )

class Top:
    def render(self):
        return translate([Case.wall_thickness * 0.5, Case.wall_thickness * 0.5, 0])(
            cube(
                [
                    Case.width - Case.wall_thickness,
                    Case.length - Case.wall_thickness,
                    Case.top_thickness,
                ]
            )
        ) - translate(
            [
                Case.wall_thickness
                + Case.board_margin
                + WemosOLEDShield.screen_x_offset,
                Case.wall_thickness
                + Case.board_margin
                + WemosOLEDShield.screen_y_offset,
            ]
        )(
            cube(
                [
                    WemosOLEDShield.screen_x_size,
                    WemosOLEDShield.screen_y_size,
                    Case.top_thickness,
                ]
            )
        )

parts.append(Case().render())

if False:
    parts.append(
        color([0, 0, 1])(
            translate(
                [
                    Case.wall_thickness + Case.board_margin,
                    Case.wall_thickness + Case.board_margin,
                    Case.floor_thickness + Case.board_z_offset,
                ]
            )(
                Wemos().render()
                + up(
                    Wemos.depth
                    + Wemos.header_height
                    + WemosOLEDShield.bottom_header_offset
                )(WemosOLEDShield().render())
            )
        )
    )

if False:
    parts.append(
        translate([0, 0, Case.floor_thickness + Case.wall_height - Case.top_thickness])(
            Top().render()
        )
    )

print("Saving File")
with open(__file__ + ".scad", "w") as f:
    f.write(scad_render(union()(parts)))

print("Saving File")
with open(__file__ + ".top.scad", "w") as f:
    f.write(scad_render(union()(Top().render())))


# -*- coding: utf-8 -*-
"""
Created on Wed Jun 13 21:47:09 2018
baidu
@author: mhy
"""

import requests
import re
import json
import time
import random
import math

#百度坐标拾取器获得 北京城区

#lat1=39.820735
#lng1=116.216091
#
#lat2=40.024808
#lng2=116.548392

#淮南市城区
lat1=32.573204
lng1=116.804016

lat2=32.722048
lng2=116.986264

all_shop_id=[]

headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36',
}

#批量生成坐标
def genPositon(lat1,lng1,lat2,lng2,step=1):
    #step单位是km，1经度度约等于111km
    step_lng = step / (111.0)
    step_lat = step / (111.0) * math.cos(math.radians(lat1))

    pos_list = []

    cur_lon = lng1 + step_lng / 2
    while (cur_lon < lng2):
        cur_lat = lat1 + step_lat / 2
        while (cur_lat < lat2):
            print([cur_lat, cur_lon])
            pos_list.append([cur_lat, cur_lon])
            cur_lat = cur_lat + step_lat

        cur_lon = cur_lon + step_lng
    return pos_list

def coords_transfer(lng,lat):
    coords=str(lng)+','+str(lat)

    #坐标转换API
    url='http://api.map.baidu.com/geoconv/v1/?coords='+coords+'&from=5&to=6&ak=X3jQGUexW0e6SpgEuGOEBPByeDA2ttm3'
    coords_req=requests.get(url=url,headers=headers)

    xy=coords_req.text

    json_dict=json.loads(xy)
    lng = json_dict['result'][0]['x']
    lat = json_dict['result'][0]['y']
    return lng,lat

def getURL(lng,lat):
    url='http://waimai.baidu.com/waimai'
    data={
    'qt': 'shoplist',
    'lat': lat,
    'lng': lng,
    }

    req=requests.get(url=url,params=data,headers=headers,allow_redirects=False)
    #发生重定向
    new_url=''
    if req.status_code==302:
        location=req.headers['Location']
        new_url='http://waimai.baidu.com'+location
    return new_url

fjw=open('shop_jw_huainan.txt','w')
#获取当前搜索中心所有商家信息
def count_shops(new_url):
    count=0
    allshops=[]
    shops=[]
    num=1

    while( (len(shops)!=0) or (num==1)):
        time.sleep(0.2+random.random())
        cur_url = new_url + '?display=json&page='+str(num)+'&count=40'
        print('URL: ' + cur_url)
        try:
            req=requests.get(url=cur_url,headers=headers,timeout=3)
            shops=re.findall('"shop_id":"[0-9]+"',req.text,re.S)
            latlngs=re.findall('"shop_lng":[0-9]+,"shop_lat":[0-9]+',req.text,re.S)
        except:
            print('wrong')

        k=0
        for shop in shops:
            sid=shop.split(':')[1]
            sid=sid[1:len(sid)-1]

            if sid not in allshops:
                allshops.append(sid)
            #如果不在所有商家列表中
            if sid not in all_shop_id:
                all_shop_id.append(sid)
                s=sid+'\t'+latlngs[k]+'\n'

                print('!!!! new SHOP ID '+s)
                fjw.write(s)
            k=k+1

        num=num+1
    count=len(allshops) #该经纬度商家计数
    return count

fout=open('format_count_huainan.txt','w')
coords=genPositon(lat1,lng1,lat2,lng2,2)
print('\ntotal coord is'+ str(len(coords)))
kk=1
for (lat,lng) in coords:
    print('\n\n-----current latitude and longitude is')
    print(lat)
    print(lng)
    print('Number '+str(kk))
    lng1,lat1=coords_transfer(lng,lat)
    new_url = getURL(lng1,lat1)
    count=count_shops(new_url)
    print(count)
    s='{"lng":'+str(lng)+',"lat":'+str(lat)+',"count":'+str(count)+'},'
    print('\n'+s)
    fout.write(s)
    kk=kk+1

fout.close()
fjw.close()


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

class PQ(object):
    """A flexible PriorityQueue wrapper to allow deletions, fast findings and updates of element priorities."""
    def __init__(self, values = None, comparator = cmp,
                 duplicates = False, store = None):
        """Returns a new PriorityQueue instance.

        Parameters:
        -----------
            values      --  The values to be initially added to the heap.
            comparator  --  The comparator function to be used to organise the values by.
                            If one is not provided then the standard comparator (cmp) is used.
            duplicates  --  This boolean flag (default = False) specifies whether duplicate
                            values are stored seperately or not.  If False, then only one instance
                            of a value can be in the PQ at a time.
            store       --  By default the PriorityQueue uses a binary heap to organise the values.
                            This can be overridden by any other instances that inherits the Storage
                            class.  See Storage for more details.
        """
        if store is None:
            from storage import binheap
            store = binheap.Storage()
        self.duplicates = duplicates
        self.storage = store
        self.storage.comparator = comparator

        self.handlesByValue = {}
        if values:
            values = set(values) or []
            handles = self.storage.heapify(values)
            if self.duplicates:
                for h in handles: self.handlesByValue[h.value] = [h]
            else:
                for h in handles: self.handlesByValue[h.value] = h

    @property
    def top(self):
        """Returns a handle to the minimum (top) value."""
        return self.storage.top()

    def pop(self):
        """Removes the top value from the PQ and returns its value."""
        handle = self.storage.pop()
        if self.duplicates:
            self.handlesByValue[handle.value].remove(handle)
        else:
            del self.handlesByValue[handle.value]
        return handle.value

    def push(self, value):
        """Pushes a new value onto the PQ.

        If the value already exists, then the value is only added again to the storage if the duplicates flag is set to False.

        Returns a handle to the value within the PQ.
        """
        if self.duplicates:
            ptr = self.storage.push(value)
            if value not in self.handlesByValue:
                self.handlesByValue[value] = []
            self.handlesByValue[value].append(ptr)
        elif value not in self.handlesByValue:
            ptr = self.storage.push(value)
            self.handlesByValue[value] = ptr
        else:
            ptr = self.handlesByValue[value]
        return ptr

    def adjust(self, value_or_handle):
        """ Called to reevaluate the position of an entry within the heap.

        This is usually called after an entry has been modified such that its position in the heap would have changed (due to a change in its priority).
        """
        handle = None
        value = value_or_handle
        if value_or_handle in self.handlesByValue:
            # A value was passed so adjust it by its handle
            handle = self.handlesByValue[value_or_handle]
        elif hasattr(value_or_handle, "value"):
            value = value_or_handle.value
            if value_or_handle.value in self.handlesByValue:
                handle = self.handlesByValue[value_or_handle.value]
        if handle:
            self.storage.adjust(handle)
        else:
            handle = self.storage.push(value)
        return handle

    def remove(self, value_or_handle):
        """Removes a given value from the PQ.

        If a handle is passed instead of a value then only the value referred by the handle is
        removed (regardless of other duplicates).
        To remove all instances of a value from the PQ, pass the value instead.
        """
        handle = None
        value = value_or_handle
        if value_or_handle in self.handlesByValue:
            # A value was passed so adjust it by its handle
            handle = self.handlesByValue[value_or_handle]
        elif hasattr(value_or_handle, "value"):
            value = value_or_handle.value
            if value_or_handle.value in self.handlesByValue:
                handle = self.handlesByValue[value_or_handle.value]
        if handle:
            self.storage.remove(handle)
        if self.duplicates:
            self.handlesByValue[handle.value].remove(handle)
        else:
            del self.handlesByValue[handle.value]

    def find(self, value):
        """Returns a handle to the first instance of a particular value.
        """
        if self.duplicates:
            v = self.handlesByValue.get(value, [])
            if v: v = v[0]
        else:
            v = self.handlesByValue.get(value, None)
        return v

    def __iter__(self):
        return iter(self.storage)

    def __len__(self):
        return self.storage.__len__()

    def __nonzero__(self):
        return self.storage.__nonzero__()


import math
import warnings
import pytest
import pyqg
import jax
import jax.numpy as jnp
import numpy as np
import pyqg_jax

BT_PARAMS = {
    "L": 2 * np.pi,
    "nx": 64,
    "beta": 0.0,
    "H": 1.0,
    "rek": 0.0,
    "rd": None,
}

@pytest.mark.parametrize(
    "param",
    [
        # Model attributes
        "nz",
        "nx",
        "ny",
        "L",
        "W",
        "rek",
        "filterfac",
        "f",
        "g",
        "beta",
        "rd",
        "H",
        "U",
        # Properties from kernel
        "nl",
        "nk",
        "kk",
        "_ik",
        "ll",
        "_il",
        "_k2l2",
        "Ubg",
        "filtr",
        "_ikQy",
        # Properties from model
        "f2",
        "dk",
        "dl",
        "dx",
        "dy",
        "M",
        "x",
        "y",
        "k",
        "l",
        "ik",
        "il",
        "wv2",
        "wv",
        "wv2i",
        # Properties from bt model
        "kd2",
        "Qy",
        "ikQy",
        "ilQx",
    ],
)
def test_default_parameters_match(param):
    jax_model = pyqg_jax.bt_model.BTModel(precision=pyqg_jax.state.Precision.DOUBLE)
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=DeprecationWarning)
        orig_model = pyqg.BTModel(log_level=0)
    jax_param = getattr(jax_model, param)
    if param in {"f", "f2"}:
        assert jax_param is None
        assert not hasattr(orig_model, param)
        return
    elif param == "H1":
        orig_param = orig_model.Hi[0]
    else:
        orig_param = getattr(orig_model, param)
    if isinstance(orig_param, np.ndarray):
        np_jax_param = np.asarray(jax_param)
        assert jax_param.shape == orig_param.shape
        assert np_jax_param.dtype == orig_param.dtype
        assert np.allclose(np_jax_param, orig_param)
    elif isinstance(orig_param, float):
        assert math.isclose(orig_param, float(jax_param))
    elif isinstance(orig_param, int):
        assert jax_param == orig_param
    else:
        orig_param = np.asarray(orig_param)
        np_jax_param = np.asarray(jax_param)
        assert jax_param.shape == orig_param.shape
        assert np_jax_param.dtype == orig_param.dtype
        assert np.allclose(np_jax_param, orig_param)

@pytest.mark.parametrize(
    "precision", [pyqg_jax.state.Precision.SINGLE, pyqg_jax.state.Precision.DOUBLE]
)
def test_match_final_step(precision):
    jax_model = pyqg_jax.bt_model.BTModel(precision=precision, **BT_PARAMS)
    start_jax_state = jax_model.create_initial_state(jax.random.PRNGKey(0))
    dt = 0.0025
    num_steps = 1000
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=DeprecationWarning)
        orig_model = pyqg.BTModel(
            log_level=0,
            dt=dt,
            tmax=dt * num_steps,
            twrite=num_steps + 10,
            **BT_PARAMS,
        )
    orig_model.q = np.asarray(start_jax_state.q).copy().astype(np.float64)

    @jax.jit
    def do_jax_steps(init_state):
        stepper = pyqg_jax.steppers.AB3Stepper(dt=dt)
        stepped_model = pyqg_jax.steppers.SteppedModel(model=jax_model, stepper=stepper)
        final_state, _ = jax.lax.scan(
            lambda carry, _: (
                stepped_model.step_model(carry),
                None,
            ),
            stepped_model.initialize_stepper_state(init_state),
            None,
            length=num_steps + 1,
        )
        return final_state

    final_jax_state = do_jax_steps(start_jax_state)
    orig_model.run()
    assert orig_model.tc == final_jax_state.tc
    abserr = jnp.abs(orig_model.q - final_jax_state.state.q)
    relerr = abserr / jnp.abs(orig_model.q)
    assert jnp.all(
        relerr < (0.025 if precision == pyqg_jax.state.Precision.SINGLE else 1e-10)
    )


""" Functional testing for /models/{model}/predictions/ endpoint.
"""
from datetime import datetime
import os
import json
from pytest_bdd import scenario, given, then, when
from fastapi.testclient import TestClient
import pytest
import shapely.wkt
from geoalchemy2.shape import from_shape
from alchemy_mock.mocking import UnifiedAlchemyMagicMock
from alchemy_mock.compat import mock
import app.main
from app.db.models import (PredictionModelRunTimestamp, PredictionModel, ModelRunGridSubsetPrediction,
                           PredictionModelGridSubset)

@pytest.fixture()
def mock_session(monkeypatch):
    """ Mocked out sqlalchemy session """
    def mock_get_session(*args):

        prediction_model = PredictionModel(id=1,
                                           abbreviation='GDPS',
                                           projection='latlon.15x.15',
                                           name='Global Deterministic Prediction System')

        geometry = ("POLYGON ((-120.525 50.77500000000001, -120.375 50.77500000000001,"
                    "-120.375 50.62500000000001, -120.525 50.62500000000001, -120.525 50.77500000000001))")
        shape = shapely.wkt.loads(geometry)

        grid = PredictionModelGridSubset(
            id=1,
            prediction_model_id=prediction_model.id,
            prediction_model=prediction_model,
            geom=from_shape(shape)
        )

        date_1 = "2020-07-22T18:00:00+00:00"
        date_2 = "2020-07-22T20:00:00+00:00"
        data = [
            (
                [mock.call.query(PredictionModelGridSubset,
                                 ModelRunGridSubsetPrediction, PredictionModel)],
                [
                    # 3 on the same hour, testing interpolation and percentiles.
                    [grid, ModelRunGridSubsetPrediction(
                        prediction_model_grid_subset_id=grid.id,
                        prediction_timestamp=datetime.fromisoformat(date_1),
                        tmp_tgl_2=[10, 11, 12, 13],
                        rh_tgl_2=[20, 30, 40, 50]), prediction_model],
                    [grid, ModelRunGridSubsetPrediction(
                        prediction_model_grid_subset_id=grid.id,
                        prediction_timestamp=datetime.fromisoformat(date_1),
                        tmp_tgl_2=[11, 12, 13, 14],
                        rh_tgl_2=[30, 40, 50, 60]), prediction_model],
                    [grid, ModelRunGridSubsetPrediction(
                        prediction_model_grid_subset_id=grid.id,
                        prediction_timestamp=datetime.fromisoformat(date_1),
                        tmp_tgl_2=[9, 10, 11, 12],
                        rh_tgl_2=[20, 30, 40, 50]), prediction_model],
                    # 1 on the hour, testing it remains unchanged.
                    [grid, ModelRunGridSubsetPrediction(
                        prediction_model_grid_subset_id=grid.id,
                        prediction_timestamp=datetime.fromisoformat(
                            "2020-07-22T19:00:00+00:00"),
                        tmp_tgl_2=[9, 9, 9, 9],
                        rh_tgl_2=[20, 20, 20, 20]), prediction_model],
                    # 3 on same hour, same values at each grid point for easy percentile testing.
                    [grid, ModelRunGridSubsetPrediction(
                        prediction_model_grid_subset_id=grid.id,
                        prediction_timestamp=datetime.fromisoformat(date_2),
                        tmp_tgl_2=[9, 9, 9, 9],
                        rh_tgl_2=[20, 20, 20, 20]), prediction_model],
                    [grid, ModelRunGridSubsetPrediction(
                        prediction_model_grid_subset_id=grid.id,
                        prediction_timestamp=datetime.fromisoformat(date_2),
                        tmp_tgl_2=[10, 10, 10, 10],
                        rh_tgl_2=[21, 21, 21, 21]), prediction_model],
                    [grid, ModelRunGridSubsetPrediction(
                        prediction_model_grid_subset_id=grid.id,
                        prediction_timestamp=datetime.fromisoformat(date_2),
                        tmp_tgl_2=[11, 11, 11, 11],
                        rh_tgl_2=[22, 22, 22, 22]), prediction_model]
                ]
            )
        ]
        mock_session = UnifiedAlchemyMagicMock(data=data)
        return mock_session

    monkeypatch.setattr(app.db.database, 'get_session', mock_get_session)

@ scenario("test_models_predictions_summaries.feature", "Get model prediction summaries from database")
def test_model_predictions_summaries_scenario():
    """ BDD Scenario for prediction summaries """

@ given("A database")
def given_a_database(mock_session):
    """ Bind the data variable """
    return {}

@ given("station <codes>")
def given_stations(codes):
    return eval(codes)

@ when("I call <endpoint>")
def when_prediction(mock_jwt_decode, given_a_database, given_stations, endpoint: str):
    client = TestClient(app.main.app)
    response = client.post(
        endpoint, headers={'Authorization': 'Bearer token'}, json={'stations': given_stations})
    given_a_database['response_json'] = response.json()

@ then('The <expected_response> is matched')
def assert_response(given_a_database, expected_response):
    """ "Catch all" test that blindly checks the actual json response against an expected response. """
    dirname = os.path.dirname(os.path.realpath(__file__))
    filename = os.path.join(dirname, expected_response)
    with open(filename) as data_file:
        expected_json = json.load(data_file)
        assert given_a_database['response_json'] == expected_json


#region ilk_giris
#variable - değişkenler
"""
skor = 12
print(skor)

name = "mehmet"
print(name)
"""
#endregion

#region notation
"""
#camel casing
okulNumarasi = 571 #ilk karakter küçük ikinci karakter büyük harfle başlar
ad = "didem"
soyad = "mumcu"
sinavNotu = 99
print(okulNumarasi, ad, soyad, sinavNotu)
"""
""""""
#undercore casing
okul_numarasi = 571 #alttire kullanılır
ad = "didem"
soyad = "mumcu"
sinav_notu = 100
print(okul_numarasi, ad, soyad, sinav_notu)

#endregion


###################################################################################################
# Copyright (c) 2022 Birgit Hillebrecht
#
# To cite this code in publications, please use
#       B. Hillebrecht and B. Unger : "Certified machine learning: Rigorous a posteriori error bounds for PDE defined PINNs", arxiV preprint available
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
###################################################################################################

import os
import sys

import numpy as np
import matplotlib.pyplot as plt

sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "..","helpers"))
from csv_helpers import import_csv
from plotting import new_fig, save_fig

if __name__ == "__main__":

    t_seq = np.linspace(0, 0.2, 101)
    fig = new_fig()
    ax = fig.add_subplot(1, 1, 1)

    cmap = plt.get_cmap("RdBu")
    colors = np.concatenate([cmap(np.linspace(1.0, 0.6, 16)),cmap(np.linspace(0, 0.4, 16)), cmap(np.linspace(0.6, 1.0, 16))])
    ls = [':', '-', '--', '-.',
          '--',':', '-.', '-',
          '-.','--', '-',':' ]
    ls = np.concatenate([ls,ls,ls,ls,ls,ls], axis = 0)

    # plot u
    index = 0
    subindex = 0
    for time in t_seq:
        data = import_csv(os.path.join(os.path.dirname(__file__), "run_tanh_kleingordon_ref_t"+"{:3.3f}".format(time)+"_simple.csv"), has_headers=True)

        ax.set( ylabel=r'$u(t,x)$')
        ax.set( xlabel="$x$")

        ax.grid(True, which='both')
        ax.set(xlim=[0,1])

        if index % 16 == 0:
            ax.plot(data[:,1:2], data[:,3:4], linewidth=1.5, color=colors[subindex], linestyle=ls[subindex], label=r'$t= $'+str(time))
            subindex = subindex +1
        elif index % 4 == 0:
            ax.plot(data[:,1:2], data[:,3:4], linewidth=1.5, color=colors[subindex], linestyle=ls[subindex])
            subindex = subindex +1
        index= index+1

    ax.legend(loc='best')
    fig.tight_layout()

    save_fig(fig, "timeseries_tanh_u", os.path.join(os.path.dirname(__file__), "..", "run_tanh_figures"))
    plt.show()

    # plot u
    fig = new_fig()
    ax = fig.add_subplot(1, 1, 1)

    index = 0
    subindex = 0
    for time in t_seq:
        data = import_csv(os.path.join(os.path.dirname(__file__), "run_tanh_kleingordon_ref_t"+"{:3.3f}".format(time)+"_simple.csv"), has_headers=True)

        ax.set( ylabel=r'$\partial_t u(t,x)$')
        ax.set( xlabel="$x$")

        ax.grid(True, which='both')
        ax.set(xlim=[0,1])

        if index % 16 == 0:
            ax.plot(data[:,1:2], data[:,2:3], linewidth=1.5, color=colors[subindex], linestyle=ls[subindex], label=r'$t= $'+str(time))
            subindex = subindex+1
        elif index% 4 == 0:
            ax.plot(data[:,1:2], data[:,2:3], linewidth=1.5, color=colors[subindex], linestyle=ls[subindex])
            subindex = subindex+1
        index= index+1

    ax.legend(loc='best')
    fig.tight_layout()

    save_fig(fig, "timeseries_tanh_dtu", os.path.join(os.path.dirname(__file__), "..", "run_tanh_figures"))
    plt.show()


import logging

import datajoint as dj

log = logging.getLogger(__name__)

class InsertBuffer(object):
    '''
    InsertBuffer: a utility class to help managed chunked inserts

    Currently requires records do not have prerequisites.
    '''
    def __init__(self, rel):
        self._rel = rel
        self._queue = []

    def insert1(self, r):
        self._queue.append(r)

    def insert(self, recs):
        self._queue += recs

    def flush(self, replace=False, skip_duplicates=False,
              ignore_extra_fields=False, allow_direct_insert=False, chunksz=1):
        '''
        flush the buffer
        XXX: use kwargs?
        XXX: ignore_extra_fields na, requires .insert() support
        '''
        qlen = len(self._queue)
        if qlen > 0 and qlen % chunksz == 0:
            try:
                self._rel().insert(self._queue,
                                   skip_duplicates=skip_duplicates,
                                   ignore_extra_fields=ignore_extra_fields,
                                   allow_direct_insert=allow_direct_insert)
                self._queue.clear()
                return True
            except dj.DataJointError as e:
                log.error('error in flush: {}'.format(e))
                raise


import multiprocessing as mp

def grava(x):
	arq = open('listapn.txt', 'w')
	arq.write(str(x)+'\n')
	arq.close()

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    mp.set_start_method('spawn')
    q = mp.Queue()
    p = mp.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()


# 수 정렬2
#
# 최악 O(nlogn)인 정렬으로 해결해야함
# 참고: https://stackoverflow.com/questions/33267096/how-to-improve-merge-sort-speed-in-python

import sys
sys.setrecursionlimit(5000)

def merge(left, right):
    result = []
    left_count = 0
    right_count = 0
    try:
        while True:
            if left[left_count] > right[right_count]:
                result.append(right[right_count])
                right_count += 1
            else:
                result.append(left[left_count])
                left_count += 1
    except:
        return result + left[left_count:] + right[right_count:]

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    return merge(merge_sort(arr[:mid]), merge_sort(arr[mid:]))

arr = []
for i in range(int(sys.stdin.readline())):
    arr.append(int(sys.stdin.readline()))

for item in merge_sort(arr):
    print(item)