# -*- coding: utf-8 -*-
"""
Service parameter based filtering widget
"""

# .. note:: This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

__author__ = 'Original authors: Mario Locati, Roberto Vallone, Matteo Ghetta, Nyall Dawson'
__date__ = '29/01/2020'
__copyright__ = 'Istituto Nazionale di Geofisica e Vulcanologia (INGV)'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

from copy import deepcopy
from typing import Optional, List, Dict

from qgis.PyQt import uic
from qgis.PyQt.QtCore import (
    pyqtSignal,
    Qt,
    QDateTime
)
from qgis.PyQt.QtWidgets import QWidget
from qgis.core import (
    QgsProject,
    QgsCoordinateReferenceSystem,
    QgsCoordinateTransform,
    QgsCsException,
    QgsSettings,
    QgsUnitTypes,
    QgsRectangle,
    QgsPointXY
)
from qgis.gui import (
    QgsMapToolExtent,
    QgsMapToolEmitPoint,
)

from qquake.gui.base_filter_widget import BaseFilterWidget
from qquake.gui.gui_utils import GuiUtils
from qquake.gui.predefined_areas_dialog import PredefinedAreasDialog
from qquake.quakeml.common import EVENT_TYPES
from qquake.services import SERVICE_MANAGER

FORM_CLASS, _ = uic.loadUiType(GuiUtils.get_ui_file_path('filter_parameter_widget_base.ui'))

class FilterParameterWidget(QWidget, FORM_CLASS, BaseFilterWidget):  # pylint: disable=too-many-public-methods
    """
    Service parameter based filtering widget
    """
    changed = pyqtSignal()

    def __init__(self,  # pylint: disable=too-many-statements
                 iface,
                 service_type: str,
                 parent: Optional[QWidget] = None):
        """Constructor."""
        super().__init__(parent)

        self.setupUi(self)

        self.scroll_area.setStyleSheet("""
            QScrollArea { background: transparent; }
            QScrollArea > QWidget > QWidget { background: transparent; }
            QScrollArea > QWidget > QScrollBar { background: 1; }
        """)

        for m in range(1, 13):
            self.earthquake_max_intensity_greater_combo.addItem(str(m), m)

        self.iface = iface
        self.previous_map_tool = None
        self.extent_tool = None
        self.customize_areas_dialog = None

        self.set_extent_from_canvas_extent(self.iface.mapCanvas().extent())
        self.set_center_from_canvas_point(self.iface.mapCanvas().extent().center())

        self.fdsn_event_start_date.dateTimeChanged.connect(self._refresh_date)
        self.min_time_check.toggled.connect(self.changed)
        self.fdsn_event_start_date.dateTimeChanged.connect(self.changed)
        self.max_time_check.toggled.connect(self.changed)
        self.fdsn_event_end_date.dateTimeChanged.connect(self.changed)
        self.min_mag_check.toggled.connect(self.changed)
        self.fdsn_event_min_magnitude.valueChanged.connect(self.changed)
        self.max_mag_check.toggled.connect(self.changed)
        self.fdsn_event_max_magnitude.valueChanged.connect(self.changed)
        self.lat_min_spinbox.valueChanged.connect(self.changed)
        self.lat_max_spinbox.valueChanged.connect(self.changed)
        self.long_min_spinbox.valueChanged.connect(self.changed)
        self.long_max_spinbox.valueChanged.connect(self.changed)
        self.lat_min_checkbox.toggled.connect(self.changed)
        self.lat_max_checkbox.toggled.connect(self.changed)
        self.long_min_checkbox.toggled.connect(self.changed)
        self.long_max_checkbox.toggled.connect(self.changed)
        self.limit_extent_checkbox.toggled.connect(self.changed)
        self.radio_rectangular_area.toggled.connect(self.changed)
        self.radio_circular_area.toggled.connect(self.changed)
        self.radio_predefined_area.toggled.connect(self.changed)
        self.circular_lat_spinbox.valueChanged.connect(self.changed)
        self.circular_long_spinbox.valueChanged.connect(self.changed)
        self.radius_min_checkbox.toggled.connect(self.changed)
        self.radius_max_checkbox.toggled.connect(self.changed)
        self.radius_min_spinbox.valueChanged.connect(self.changed)
        self.radius_max_spinbox.valueChanged.connect(self.changed)
        self.radius_unit_combobox.currentIndexChanged.connect(self.changed)
        self.earthquake_max_intensity_greater_check.toggled.connect(self.changed)
        self.earthquake_max_intensity_greater_combo.currentIndexChanged.connect(self.changed)
        self.earthquake_number_mdps_greater_check.toggled.connect(self.changed)
        self.earthquake_number_mdps_greater_spin.valueChanged.connect(self.changed)
        self.output_table_options_widget.changed.connect(self.changed)
        self.event_type_check.toggled.connect(self.changed)
        self.event_type_combo.currentIndexChanged.connect(self.changed)
        self.events_updated_after_check.toggled.connect(self.changed)
        self.events_updated_after.dateChanged.connect(self.changed)

        self.rect_extent_draw_on_map.clicked.connect(self.draw_rect_on_map)
        self.circle_center_draw_on_map.clicked.connect(self.draw_center_on_map)

        self.radio_rectangular_area.toggled.connect(self._enable_widgets)
        self.radio_circular_area.toggled.connect(self._enable_widgets)
        self.radio_predefined_area.toggled.connect(self._enable_widgets)
        self.limit_extent_checkbox.toggled.connect(self._enable_widgets)
        self.lat_min_checkbox.toggled.connect(self._enable_widgets)
        self.lat_max_checkbox.toggled.connect(self._enable_widgets)
        self.long_min_checkbox.toggled.connect(self._enable_widgets)
        self.long_max_checkbox.toggled.connect(self._enable_widgets)
        self.radius_min_checkbox.toggled.connect(self._enable_widgets)
        self.radius_max_checkbox.toggled.connect(self._enable_widgets)
        self.min_time_check.toggled.connect(self._enable_widgets)
        self.max_time_check.toggled.connect(self._enable_widgets)
        self.min_mag_check.toggled.connect(self._enable_widgets)
        self.max_mag_check.toggled.connect(self._enable_widgets)
        self.output_table_options_widget.changed.connect(self._enable_widgets)
        self.earthquake_max_intensity_greater_check.toggled.connect(self._enable_widgets)
        self.earthquake_number_mdps_greater_check.toggled.connect(self._enable_widgets)
        self._enable_widgets()

        self._populated_predefined_areas()
        SERVICE_MANAGER.areasChanged.connect(self._populated_predefined_areas)
        self.combo_predefined_area.currentIndexChanged.connect(self._use_predefined_area)
        self.radio_predefined_area.toggled.connect(self._use_predefined_area)

        self.button_customize_areas.clicked.connect(self._customize_areas)

        self.event_type_check.toggled.connect(self._enable_widgets)
        for event_type in EVENT_TYPES:
            self.event_type_combo.addItem(event_type, event_type)

        self.events_updated_after_check.toggled.connect(self._enable_widgets)

        self.service_type = None
        self.service_id = None
        self.set_service_type(service_type)

    def is_valid(self) -> bool:
        for check in [self.min_time_check, self.max_time_check, self.min_mag_check, self.max_mag_check,
                      self.limit_extent_checkbox, self.earthquake_max_intensity_greater_check,
                      self.earthquake_number_mdps_greater_check]:
            if check.isChecked():
                return True

        return False

    def set_service_type(self, service_type: str):
        self.service_type = service_type

        self.time_coverage_group.setVisible(
            self.service_type in (SERVICE_MANAGER.MACROSEISMIC, SERVICE_MANAGER.FDSNEVENT, SERVICE_MANAGER.FDSNSTATION))
        self.magnitude_group.setVisible(self.service_type in (SERVICE_MANAGER.MACROSEISMIC, SERVICE_MANAGER.FDSNEVENT))
        self.macroseismic_data_group.setVisible(self.service_type == SERVICE_MANAGER.MACROSEISMIC)

        self.output_table_options_widget.set_service_type(service_type)

    def set_service_id(self, service_id: str):  # pylint:disable=too-many-branches
        self.service_id = service_id

        service_config = SERVICE_MANAGER.service_details(self.service_type, self.service_id)

        self.output_table_options_widget.set_service_id(service_id)

        if not service_config['settings'].get('querycircular', False):
            if self.radio_circular_area.isChecked():
                self.radio_rectangular_area.setChecked(True)
            self.radio_circular_area.setEnabled(False)
        else:
            self.radio_circular_area.setEnabled(True)

        if not service_config['settings'].get('queryeventtype', False):
            if self.event_type_check.isChecked():
                self.event_type_check.setChecked(False)
            self.event_type_check.setEnabled(False)
        else:
            self.event_type_check.setEnabled(True)

        if not service_config['settings'].get('queryupdatedafter', False):
            if self.events_updated_after_check.isChecked():
                self.events_updated_after_check.setChecked(False)
            self.events_updated_after_check.setEnabled(False)
        else:
            self.events_updated_after_check.setEnabled(True)

        self.radius_unit_combobox.clear()
        self.radius_unit_combobox.addItem(self.tr('Degrees'), QgsUnitTypes.DistanceDegrees)
        if service_config['settings'].get('querycircularradiuskm', False):
            self.radius_unit_combobox.insertItem(0, self.tr('Kilometers'), QgsUnitTypes.DistanceKilometers)
        self.radius_unit_combobox.setCurrentIndex(0)

    def restore_settings(self, prefix: str):  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
        s = QgsSettings()

        if self.service_id:
            service_config = SERVICE_MANAGER.service_details(self.service_type, self.service_id)
        else:
            service_config = None

        last_event_start_date = s.value('/plugins/qquake/{}_last_event_start_date'.format(prefix))
        if last_event_start_date is not None:
            self.fdsn_event_start_date.setDateTime(last_event_start_date)
        last_event_end_date = s.value('/plugins/qquake/{}_last_event_end_date'.format(prefix))
        if last_event_end_date is not None:
            self.fdsn_event_end_date.setDateTime(last_event_end_date)
        last_event_min_magnitude = s.value('/plugins/qquake/{}_last_event_min_magnitude'.format(prefix))
        if last_event_min_magnitude is not None:
            self.fdsn_event_min_magnitude.setValue(float(last_event_min_magnitude))
        last_event_max_magnitude = s.value('/plugins/qquake/{}_last_event_max_magnitude'.format(prefix))
        if last_event_max_magnitude is not None:
            self.fdsn_event_max_magnitude.setValue(float(last_event_max_magnitude))
        self.limit_extent_checkbox.setChecked(
            s.value('/plugins/qquake/{}_last_event_extent_enabled2'.format(prefix), False, bool))
        self.radio_predefined_area.setChecked(
            s.value('/plugins/qquake/{}_last_event_extent_named'.format(prefix), False, bool))
        last_area = s.value('/plugins/qquake/{}_last_event_extent_name'.format(prefix), '', str)
        if last_area:
            self.combo_predefined_area.setCurrentIndex(self.combo_predefined_area.findData(last_area))
        self.radio_rectangular_area.setChecked(
            s.value('/plugins/qquake/{}_last_event_extent_rect2'.format(prefix), False, bool))

        if not service_config or service_config['settings'].get('querycircular', False):
            self.radio_circular_area.setChecked(
                s.value('/plugins/qquake/{}_last_event_extent_circle2'.format(prefix), False, bool))
        self.lat_min_checkbox.setChecked(
            s.value('/plugins/qquake/{}_last_event_min_lat_checked2'.format(prefix), False, bool))
        self.lat_max_checkbox.setChecked(
            s.value('/plugins/qquake/{}_last_event_max_lat_checked2'.format(prefix), False, bool))
        self.long_min_checkbox.setChecked(
            s.value('/plugins/qquake/{}_last_event_min_long_checked2'.format(prefix), False, bool))
        self.long_max_checkbox.setChecked(
            s.value('/plugins/qquake/{}_last_event_max_long_checked2'.format(prefix), False, bool))

        self.radius_min_checkbox.setChecked(
            s.value('/plugins/qquake/{}_last_event_circle_radius_min_checked2'.format(prefix), False, bool))
        self.radius_max_checkbox.setChecked(
            s.value('/plugins/qquake/{}_last_event_circle_radius_max_checked2'.format(prefix), False, bool))

        self.radius_unit_combobox.setCurrentIndex(
            max(0, self.radius_unit_combobox.findData(
                s.value('/plugins/qquake/{}_last_event_circle_unit'.format(prefix),
                        int(QgsUnitTypes.DistanceKilometers), int))))

        last_event_min_lat = s.value('/plugins/qquake/{}_last_event_min_lat'.format(prefix))
        if last_event_min_lat is not None:
            self.lat_min_spinbox.setValue(float(last_event_min_lat))
        last_event_max_lat = s.value('/plugins/qquake/{}_last_event_max_lat'.format(prefix))
        if last_event_max_lat is not None:
            self.lat_max_spinbox.setValue(float(last_event_max_lat))
        last_event_min_long = s.value('/plugins/qquake/{}_last_event_min_long'.format(prefix))
        if last_event_min_long is not None:
            self.long_min_spinbox.setValue(float(last_event_min_long))
        last_event_max_long = s.value('/plugins/qquake/{}_last_event_max_long'.format(prefix))
        if last_event_max_long is not None:
            self.long_max_spinbox.setValue(float(last_event_max_long))

        last_event_circle_lat = s.value('/plugins/qquake/{}_last_event_circle_lat'.format(prefix))
        if last_event_circle_lat is not None:
            self.circular_lat_spinbox.setValue(float(last_event_circle_lat))
        last_event_circle_long = s.value('/plugins/qquake/{}_last_event_circle_long'.format(prefix))
        if last_event_circle_long is not None:
            self.circular_long_spinbox.setValue(float(last_event_circle_long))

        last_event_min_radius = s.value('/plugins/qquake/{}_last_event_circle_min_radius'.format(prefix))
        if last_event_min_radius is not None:
            self.radius_min_spinbox.setValue(float(last_event_min_radius))
        last_event_max_radius = s.value('/plugins/qquake/{}_last_event_circle_max_radius'.format(prefix))
        if last_event_max_radius is not None:
            self.radius_max_spinbox.setValue(float(last_event_max_radius))

        self.min_time_check.setChecked(
            s.value('/plugins/qquake/{}_last_event_min_time_checked2'.format(prefix), False, bool))
        self.max_time_check.setChecked(
            s.value('/plugins/qquake/{}_last_event_max_time_checked2'.format(prefix), False, bool))
        self.min_mag_check.setChecked(
            s.value('/plugins/qquake/{}_last_event_min_mag_checked2'.format(prefix), False, bool))
        self.max_mag_check.setChecked(
            s.value('/plugins/qquake/{}_last_event_max_mag_checked2'.format(prefix), False, bool))
        self.earthquake_max_intensity_greater_check.setChecked(
            s.value('/plugins/qquake/{}_last_event_max_intensity_greater_checked2'.format(prefix), False, bool))
        v = s.value('/plugins/qquake/{}_last_event_max_intensity_greater'.format(prefix))
        if v is not None:
            self.earthquake_max_intensity_greater_combo.setCurrentIndex(
                self.earthquake_max_intensity_greater_combo.findData(float(v)))

        self.earthquake_number_mdps_greater_check.setChecked(
            s.value('/plugins/qquake/{}_last_event_mdps_greater_checked2'.format(prefix), False, bool))
        v = s.value('/plugins/qquake/{}_last_event_mdps_greater'.format(prefix))
        if v is not None:
            self.earthquake_number_mdps_greater_spin.setValue(int(v))

        self.output_table_options_widget.restore_settings(prefix, 'last')

        self.event_type_check.setChecked(
            s.value('/plugins/qquake/{}_last_event_type_checked'.format(prefix), False, bool))
        last_event_type = s.value('/plugins/qquake/{}_last_event_type'.format(prefix), '', str)
        if last_event_type is not None:
            self.event_type_combo.setCurrentIndex(self.event_type_combo.findData(last_event_type))

        self.events_updated_after_check.setChecked(
            s.value('/plugins/qquake/{}_events_updated_after_checked'.format(prefix), False, bool))
        last_updated_after_date = s.value('/plugins/qquake/{}_events_updated_after_date'.format(prefix))
        if last_updated_after_date is not None:
            self.events_updated_after.setDateTime(last_updated_after_date)

    def save_settings(self, prefix: str):
        s = QgsSettings()
        s.setValue('/plugins/qquake/{}_last_event_start_date'.format(prefix), self.fdsn_event_start_date.dateTime())
        s.setValue('/plugins/qquake/{}_last_event_end_date'.format(prefix), self.fdsn_event_end_date.dateTime())
        s.setValue('/plugins/qquake/{}_last_event_min_magnitude'.format(prefix), self.fdsn_event_min_magnitude.value())
        s.setValue('/plugins/qquake/{}_last_event_max_magnitude'.format(prefix), self.fdsn_event_max_magnitude.value())

        s.setValue('/plugins/qquake/{}_last_event_extent_enabled2'.format(prefix),
                   self.limit_extent_checkbox.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_extent_named'.format(prefix), self.radio_predefined_area.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_extent_name'.format(prefix), self.combo_predefined_area.currentData())

        s.setValue('/plugins/qquake/{}_last_event_extent_rect2'.format(prefix), self.radio_rectangular_area.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_extent_circle2'.format(prefix), self.radio_circular_area.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_min_lat_checked2'.format(prefix), self.lat_min_checkbox.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_min_lat'.format(prefix), self.lat_min_spinbox.value())
        s.setValue('/plugins/qquake/{}_last_event_max_lat_checked2'.format(prefix), self.lat_max_checkbox.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_max_lat'.format(prefix), self.lat_max_spinbox.value())
        s.setValue('/plugins/qquake/{}_last_event_min_long_checked2'.format(prefix), self.long_min_checkbox.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_min_long'.format(prefix), self.long_min_spinbox.value())
        s.setValue('/plugins/qquake/{}_last_event_max_long_checked2'.format(prefix), self.long_max_checkbox.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_max_long'.format(prefix), self.long_max_spinbox.value())

        s.setValue('/plugins/qquake/{}_last_event_circle_long'.format(prefix), self.circular_long_spinbox.value())
        s.setValue('/plugins/qquake/{}_last_event_circle_lat'.format(prefix), self.circular_lat_spinbox.value())
        s.setValue('/plugins/qquake/{}_last_event_circle_radius_min_checked2'.format(prefix),
                   self.radius_min_checkbox.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_circle_radius_max_checked2'.format(prefix),
                   self.radius_max_checkbox.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_circle_min_radius'.format(prefix), self.radius_min_spinbox.value())
        s.setValue('/plugins/qquake/{}_last_event_circle_max_radius'.format(prefix), self.radius_max_spinbox.value())
        s.setValue('/plugins/qquake/{}_last_event_circle_unit'.format(prefix),
                   int(self.radius_unit_combobox.currentData()))

        s.setValue('/plugins/qquake/{}_last_event_max_intensity_greater_checked2'.format(prefix),
                   self.earthquake_max_intensity_greater_check.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_max_intensity_greater'.format(prefix),
                   self.earthquake_max_intensity_greater_combo.currentData())
        s.setValue('/plugins/qquake/{}_last_event_mdps_greater_checked2'.format(prefix),
                   self.earthquake_number_mdps_greater_check.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_mdps_greater'.format(prefix),
                   self.earthquake_number_mdps_greater_spin.value())

        s.setValue('/plugins/qquake/{}_last_event_min_time_checked2'.format(prefix), self.min_time_check.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_max_time_checked2'.format(prefix), self.max_time_check.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_min_mag_checked2'.format(prefix), self.min_mag_check.isChecked())
        s.setValue('/plugins/qquake/{}_last_event_max_mag_checked2'.format(prefix), self.max_mag_check.isChecked())

        self.output_table_options_widget.save_settings(prefix, 'last')

        s.setValue('/plugins/qquake/{}_last_event_type'.format(prefix), self.event_type_combo.currentData())
        s.setValue('/plugins/qquake/{}_last_event_type_checked'.format(prefix),
                   self.event_type_check.isChecked())

        s.setValue('/plugins/qquake/{}_events_updated_after_date'.format(prefix), self.events_updated_after.dateTime())
        s.setValue('/plugins/qquake/{}_events_updated_after_checked'.format(prefix),
                   self.events_updated_after_check.isChecked())

    def _populated_predefined_areas(self):
        """
        Populates the predefined area choices
        """
        self.combo_predefined_area.clear()
        for name in SERVICE_MANAGER.available_predefined_bounding_boxes():
            extent = SERVICE_MANAGER.predefined_bounding_box(name)
            self.combo_predefined_area.addItem(extent['title'], name)

    def _use_predefined_area(self):
        """
        Retrieves the selected predefined area details and updates the widget state accordingly
        """
        if not self.radio_predefined_area.isChecked():
            return

        selected_extent_id = self.combo_predefined_area.currentData()
        if selected_extent_id not in SERVICE_MANAGER.available_predefined_bounding_boxes():
            return

        extent = SERVICE_MANAGER.predefined_bounding_box(selected_extent_id)['boundingbox']
        self.lat_min_spinbox.setValue(extent[1])
        self.lat_max_spinbox.setValue(extent[3])
        self.long_min_spinbox.setValue(extent[0])
        self.long_max_spinbox.setValue(extent[2])
        self.lat_max_checkbox.setChecked(True)
        self.long_max_checkbox.setChecked(True)
        self.lat_min_checkbox.setChecked(True)
        self.long_min_checkbox.setChecked(True)

    def set_extent_from_canvas_extent(self, rect: QgsRectangle):
        """
        Sets the widget extent from the canvas extent
        """
        ct = QgsCoordinateTransform(self.iface.mapCanvas().mapSettings().destinationCrs(),
                                    QgsCoordinateReferenceSystem('EPSG:4326'), QgsProject.instance())
        try:
            rect = ct.transformBoundingBox(rect)
            self.lat_min_spinbox.setValue(rect.yMinimum())
            self.lat_max_spinbox.setValue(rect.yMaximum())
            self.long_min_spinbox.setValue(rect.xMinimum())
            self.long_max_spinbox.setValue(rect.xMaximum())
        except QgsCsException:
            pass

    def set_center_from_canvas_point(self, point: QgsPointXY):
        """
        Sets the widget center point from a canvas point
        """
        ct = QgsCoordinateTransform(self.iface.mapCanvas().mapSettings().destinationCrs(),
                                    QgsCoordinateReferenceSystem('EPSG:4326'), QgsProject.instance())
        try:
            point = ct.transform(point)
            self.circular_lat_spinbox.setValue(point.y())
            self.circular_long_spinbox.setValue(point.x())
        except QgsCsException:
            pass

    def _enable_widgets(self):
        """
        Selectively enables widgets based on overall state
        """
        for w in [self.lat_min_checkbox,
                  self.lat_max_checkbox,
                  self.long_min_checkbox,
                  self.long_max_checkbox,
                  self.lat_min_spinbox,
                  self.lat_max_spinbox,
                  self.long_min_spinbox,
                  self.long_max_spinbox,
                  self.label_rect_lat,
                  self.label_rect_long,
                  self.rect_extent_draw_on_map]:
            w.setEnabled(self.radio_rectangular_area.isChecked() and self.limit_extent_checkbox.isChecked())
        self.lat_min_spinbox.setEnabled(self.lat_min_spinbox.isEnabled() and self.lat_min_checkbox.isChecked())
        self.lat_max_spinbox.setEnabled(self.lat_max_spinbox.isEnabled() and self.lat_max_checkbox.isChecked())
        self.long_min_spinbox.setEnabled(self.long_min_spinbox.isEnabled() and self.long_min_checkbox.isChecked())
        self.long_max_spinbox.setEnabled(self.long_max_spinbox.isEnabled() and self.long_max_checkbox.isChecked())

        self.combo_predefined_area.setEnabled(self.radio_predefined_area.isChecked())

        for w in [self.circular_lat_spinbox,
                  self.circular_long_spinbox,
                  self.radius_min_checkbox,
                  self.radius_min_spinbox,
                  self.radius_max_checkbox,
                  self.radius_max_spinbox,
                  self.label_circ_center,
                  self.label_circ_radius,
                  self.label_circ_lat,
                  self.label_circ_long,
                  self.circle_center_draw_on_map,
                  self.radius_unit_combobox]:
            w.setEnabled(self.radio_circular_area.isChecked() and self.limit_extent_checkbox.isChecked())
        self.radius_min_spinbox.setEnabled(self.radius_min_spinbox.isEnabled() and self.radius_min_checkbox.isChecked())
        self.radius_max_spinbox.setEnabled(self.radius_max_spinbox.isEnabled() and self.radius_max_checkbox.isChecked())

        self.fdsn_event_start_date.setEnabled(self.min_time_check.isChecked())
        self.fdsn_event_end_date.setEnabled(self.max_time_check.isChecked())
        self.fdsn_event_min_magnitude.setEnabled(self.min_mag_check.isChecked())
        self.fdsn_event_max_magnitude.setEnabled(self.max_mag_check.isChecked())

        self.earthquake_max_intensity_greater_combo.setEnabled(self.earthquake_max_intensity_greater_check.isChecked())
        self.earthquake_number_mdps_greater_spin.setEnabled(self.earthquake_number_mdps_greater_check.isChecked())

        self.event_type_combo.setEnabled(self.event_type_check.isChecked())
        self.events_updated_after.setEnabled(self.events_updated_after_check.isChecked())

    def draw_rect_on_map(self):
        """
        Triggers drawing an extent rectangle on the map
        """
        self.previous_map_tool = self.iface.mapCanvas().mapTool()
        if not self.extent_tool:
            self.extent_tool = QgsMapToolExtent(self.iface.mapCanvas())
            self.extent_tool.extentChanged.connect(self.extent_drawn)
            self.extent_tool.deactivated.connect(self.deactivate_tool)
        self.iface.mapCanvas().setMapTool(self.extent_tool)
        self.window().setVisible(False)

    def draw_center_on_map(self):
        """
        Triggers picking a center point from the map
        """
        self.previous_map_tool = self.iface.mapCanvas().mapTool()
        if not self.extent_tool:
            self.extent_tool = QgsMapToolEmitPoint(self.iface.mapCanvas())
            self.extent_tool.canvasClicked.connect(self.center_picked)
            self.extent_tool.deactivated.connect(self.deactivate_tool)
        self.iface.mapCanvas().setMapTool(self.extent_tool)
        self.window().setVisible(False)

    def extent_drawn(self, extent: QgsRectangle):
        """
        Called after an extent is drawn on the canvas
        """
        self.set_extent_from_canvas_extent(extent)
        self.iface.mapCanvas().setMapTool(self.previous_map_tool)
        self.window().setVisible(True)
        self.previous_map_tool = None
        self.extent_tool = None

    def center_picked(self, point: QgsPointXY, button):  # pylint: disable=unused-argument
        """
        Called after a center point is picked on the canvas
        """
        self.set_center_from_canvas_point(point)
        self.iface.mapCanvas().setMapTool(self.previous_map_tool)
        self.window().setVisible(True)
        self.previous_map_tool = None
        self.extent_tool = None

    def deactivate_tool(self):
        """
        Called when the current tool should be deactivated
        """
        self.window().setVisible(True)
        self.previous_map_tool = None
        self.extent_tool = None

    def _refresh_date(self):
        """
        Avoids negative date intervals by checking start_date > end_date
        """

        if self.fdsn_event_start_date.dateTime() > self.fdsn_event_end_date.dateTime():
            self.fdsn_event_end_date.setDate(self.fdsn_event_start_date.date())

    def set_date_range_limits(self, date_start: Optional[QDateTime] = None, date_end: Optional[QDateTime] = None):
        """
        Sets the widget date range limits
        """
        if date_start:
            self.fdsn_event_start_date.setMinimumDateTime(date_start)

            self.fdsn_event_start_date.setDateTime(date_start)
            self.min_time_check.setText(
                self.tr("Start (from {})").format(date_start.toString('yyyy-MM-dd hh:mm:ss')))
        else:
            self.fdsn_event_start_date.clearMinimumDate()

            self.min_time_check.setText(self.tr("Start"))

        if date_end:
            self.fdsn_event_start_date.setMaximumDateTime(date_end)

            self.max_time_check.setText(
                self.tr("End (until {})").format(date_end.toString('yyyy-MM-dd hh:mm:ss')))
        else:
            self.fdsn_event_start_date.clearMaximumDate()

            self.max_time_check.setText(self.tr("End"))

        if date_start:
            self.fdsn_event_end_date.setMinimumDateTime(date_start)
        else:
            self.fdsn_event_end_date.clearMinimumDate()
        if date_end:
            self.fdsn_event_end_date.setMaximumDateTime(date_end)
        else:
            self.fdsn_event_end_date.clearMaximumDate()

        # just make a week difference from START date
        if date_start:
            self.fdsn_event_end_date.setDateTime(date_start.addDays(7))

    def set_current_date_range(self, date_start: Optional[QDateTime] = None, date_end: Optional[QDateTime] = None):
        """
        Sets the current widget date range
        """
        if date_start is not None:
            self.fdsn_event_start_date.setDateTime(date_start)
            self.min_time_check.setChecked(True)
        else:
            self.min_time_check.setChecked(False)

        if date_end is not None:
            self.fdsn_event_end_date.setDateTime(date_end)
            self.max_time_check.setChecked(True)
        else:
            self.max_time_check.setChecked(False)

    def set_predefined_bounding_box(self, box):
        """
        Sets the current predefined bounding box
        """
        self.radio_predefined_area.setChecked(True)
        self.combo_predefined_area.setCurrentIndex(self.combo_predefined_area.findData(box))

    def set_min_latitude(self, lat: float):
        """
        Sets minimum latitude
        """
        self.radio_rectangular_area.setChecked(True)
        self.lat_min_spinbox.setValue(float(lat))

    def set_max_latitude(self, lat: float):
        """
        Sets maximum latitude
        """
        self.radio_rectangular_area.setChecked(True)
        self.lat_max_spinbox.setValue(float(lat))

    def set_min_longitude(self, long: float):
        """
        Sets minimum longitude
        """
        self.radio_rectangular_area.setChecked(True)
        self.long_min_spinbox.setValue(float(long))

    def set_max_longitude(self, long: float):
        """
        Sets the maximum longitude
        """
        self.radio_rectangular_area.setChecked(True)
        self.long_max_spinbox.setValue(float(long))

    def set_circle_longitude(self, long: float):
        """
        Sets the circle center longitude
        """
        self.radio_circular_area.setChecked(True)
        self.circular_long_spinbox.setValue(float(long))

    def set_circle_latitude(self, lat: float):
        """
        Sets the circle center latitude
        """
        self.radio_circular_area.setChecked(True)
        self.circular_lat_spinbox.setValue(float(lat))

    def set_min_circle_radius(self, radius: float):
        """
        Sets the minimum circle radius
        """
        self.radius_min_checkbox.setChecked(True)
        self.radius_min_spinbox.setValue(float(radius))

    def set_max_circle_radius(self, radius: float):
        """
        Sets the maximum circle radius
        """
        self.radius_max_checkbox.setChecked(True)
        self.radius_max_spinbox.setValue(float(radius))

    def set_min_magnitude(self, mag: Optional[float]):
        """
        Sets the minimum magnitude filter value
        """
        self.min_mag_check.setChecked(mag is not None)
        if mag is not None:
            self.fdsn_event_min_magnitude.setValue(float(mag))

    def set_max_magnitude(self, mag: Optional[float]):
        """
        Sets the maximum magnitude filter value
        """
        self.max_mag_check.setChecked(mag is not None)
        if mag is not None:
            self.fdsn_event_max_magnitude.setValue(float(mag))

    def set_max_intensity_greater(self, intensity: Optional[float]):
        """
        Sets the intensity greater than filter value
        """
        self.earthquake_max_intensity_greater_check.setChecked(intensity is not None)
        if intensity is not None:
            self.earthquake_max_intensity_greater_combo.setCurrentIndex(
                self.earthquake_max_intensity_greater_combo.findData(float(intensity)))

    def set_mdps_greater_than(self, mdps: Optional[float]):
        """
        Sets the MDPs greater than filter value
        """
        self.earthquake_number_mdps_greater_check.setChecked(mdps is not None)
        if mdps is not None:
            self.earthquake_number_mdps_greater_spin.setValue(float(mdps))

    def set_event_type(self, event_type: Optional[str]):
        """
        Sets the event type than filter value
        """
        self.event_type_check.setChecked(event_type is not None)
        if event_type is not None:
            self.event_type_combo.setCurrentIndex(self.event_type_combo.findData(event_type))

    def set_updated_after(self, after: Optional[QDateTime]):
        """
        Sets the updated after date
        """
        self.events_updated_after_check.setChecked(after is not None)
        if after is not None:
            self.events_updated_after.setDateTime(after)

    def set_extent_limit(self, box: List[float]):
        """
        Sets the extent limits
        """
        self.long_min_spinbox.setMinimum(box[0])
        self.long_max_spinbox.setMinimum(box[0])
        self.lat_min_spinbox.setMinimum(box[1])
        self.lat_max_spinbox.setMinimum(box[1])
        self.long_min_spinbox.setMaximum(box[2])
        self.long_max_spinbox.setMaximum(box[2])
        self.lat_min_spinbox.setMaximum(box[3])
        self.lat_max_spinbox.setMaximum(box[3])

        # reset previously selected predefined area, now that new min/max area has been applied
        self._use_predefined_area()

    def start_date(self) -> Optional[QDateTime]:
        """
        Returns the start date
        """
        if self.service_type not in (
                SERVICE_MANAGER.MACROSEISMIC, SERVICE_MANAGER.FDSNEVENT, SERVICE_MANAGER.FDSNSTATION):
            return None

        return self.fdsn_event_start_date.dateTime() if self.min_time_check.isChecked() else None

    def end_date(self) -> Optional[QDateTime]:
        """
        Returns the start date
        """
        if self.service_type not in (
                SERVICE_MANAGER.MACROSEISMIC, SERVICE_MANAGER.FDSNEVENT, SERVICE_MANAGER.FDSNSTATION):
            return None

        return self.fdsn_event_end_date.dateTime() if self.max_time_check.isChecked() else None

    def min_magnitude(self) -> Optional[float]:
        """
        Returns the maximum magnitude
        """
        if self.service_type not in (SERVICE_MANAGER.MACROSEISMIC, SERVICE_MANAGER.FDSNEVENT):
            return None

        return self.fdsn_event_min_magnitude.value() if self.min_mag_check.isChecked() else None

    def max_magnitude(self) -> Optional[float]:
        """
        Returns the maximum magnitude
        """
        if self.service_type not in (SERVICE_MANAGER.MACROSEISMIC, SERVICE_MANAGER.FDSNEVENT):
            return None

        return self.fdsn_event_max_magnitude.value() if self.max_mag_check.isChecked() else None

    def extent_rect(self) -> bool:
        """
        Returns True if extent should be filtered by rectangle
        """
        return self.limit_extent_checkbox.isChecked() and (self.radio_rectangular_area.isChecked() or
                                                           self.radio_predefined_area.isChecked())

    def min_latitude(self) -> Optional[float]:
        """
        Returns the minimum latitude for the extent
        """
        return self.lat_min_spinbox.value() if self.lat_min_checkbox.isChecked() else None

    def max_latitude(self) -> Optional[float]:
        """
        Returns the maximum latitude for the extent
        """
        return self.lat_max_spinbox.value() if self.lat_max_checkbox.isChecked() else None

    def min_longitude(self) -> Optional[float]:
        """
        Returns the minimum longitude for the extent
        """
        return self.long_min_spinbox.value() if self.long_min_checkbox.isChecked() else None

    def max_longitude(self) -> Optional[float]:
        """
        Returns the maximum longitude for the extent
        """
        return self.long_max_spinbox.value() if self.long_max_checkbox.isChecked() else None

    def limit_extent_circle(self) -> bool:
        """
        Returns True if extent should be limited to a circle region
        """
        return self.limit_extent_checkbox.isChecked() and self.radio_circular_area.isChecked()

    def circle_latitude(self) -> float:
        """
        Returns the circle longitude
        """
        return self.circular_lat_spinbox.value()

    def circle_longitude(self) -> float:
        """
        Returns the circle longitude
        """
        return self.circular_long_spinbox.value()

    def circle_min_radius(self) -> Optional[float]:
        """
        Returns the minimum circle radius distance
        """
        return self.radius_min_spinbox.value() if self.radius_min_checkbox.isChecked() else None

    def circle_max_radius(self) -> Optional[float]:
        """
        Returns the maximum circle radius distance
        """
        return self.radius_max_spinbox.value() if self.radius_max_checkbox.isChecked() else None

    def circle_radius_unit(self) -> QgsUnitTypes.DistanceUnit:
        """
        Returns the circle radius unit
        """
        return self.radius_unit_combobox.currentData()

    def earthquake_max_intensity_greater(self) -> Optional[float]:
        """
        Returns the max intensity greater than filter value
        """
        if self.service_type != SERVICE_MANAGER.MACROSEISMIC:
            return None
        return self.earthquake_max_intensity_greater_combo.currentData() if self.earthquake_max_intensity_greater_check.isChecked() else None

    def earthquake_number_mdps_greater(self) -> Optional[float]:
        """
        Returns the MDP greater than filter value
        """
        if self.service_type != SERVICE_MANAGER.MACROSEISMIC:
            return None

        return self.earthquake_number_mdps_greater_spin.value() if self.earthquake_number_mdps_greater_check.isChecked() else None

    def convert_negative_depths(self) -> bool:
        return self.output_options_widget.convert_negative_depths()

    def depth_unit(self) -> QgsUnitTypes.DistanceUnit:
        return self.output_options_widget.depth_unit()

    def event_type(self) -> Optional[str]:
        """
        Returns the selected event type, or None
        """
        return self.event_type_combo.currentData() if self.event_type_check.isChecked() else None

    def updated_after(self) -> Optional[QDateTime]:
        """
        Returns the selected updated after date, or None
        """
        return self.events_updated_after.dateTime() if self.events_updated_after_check.isChecked() else None

    def output_type(self) -> str:
        return self.output_table_options_widget.output_type()

    def output_fields(self) -> Optional[List[str]]:
        return self.output_table_options_widget.output_fields

    def selected_styles(self) -> Dict[str, str]:
        return self.output_table_options_widget.selected_styles()

    def to_service_definition(self) -> dict:
        """
        Converts the widget state to a service definition
        """
        base_config = deepcopy(SERVICE_MANAGER.service_details(self.service_type, self.service_id))

        defaults = base_config.get('default', {})

        for k, v in {'datestart': self.start_date().toString(Qt.ISODate) if self.start_date() else None,
                     'dateend': self.end_date().toString(Qt.ISODate) if self.end_date() else None,
                     'boundingboxpredefined': self.combo_predefined_area.currentData() if self.radio_predefined_area.isChecked() else None,
                     'minimumlatitude': self.min_latitude() if self.radio_rectangular_area.isChecked() else None,
                     'maximumlatitude': self.max_latitude() if self.radio_rectangular_area.isChecked() else None,
                     'minimumlongitude': self.min_longitude() if self.radio_rectangular_area.isChecked() else None,
                     'maximumlongitude': self.max_longitude() if self.radio_rectangular_area.isChecked() else None,
                     'circlelatitude': self.circle_latitude() if self.radio_circular_area.isChecked() else None,
                     'circlelongitude': self.circle_longitude() if self.radio_circular_area.isChecked() else None,
                     'minimumcircleradius': self.circle_min_radius() if self.radio_circular_area.isChecked() else None,
                     'maximumcircleradius': self.circle_max_radius() if self.radio_circular_area.isChecked() else None,
                     'minimummagnitude': self.min_magnitude(),
                     'maximummagnitude': self.max_magnitude(),
                     'macromaxintensitygreater': self.earthquake_max_intensity_greater(),
                     'macromdpsgreaterthan': self.earthquake_number_mdps_greater(),
                     'eventtype': self.event_type(),
                     'updatedafter': self.updated_after().toString(Qt.ISODate) if self.updated_after() else None,
                     }.items():
            if v:
                defaults[k] = v
            elif k in defaults:
                del defaults[k]

        base_config['default'] = defaults
        return base_config

    def _customize_areas(self):
        """
        Shows the customise areas dialog
        """
        if self.customize_areas_dialog:
            self.customize_areas_dialog.show()
            return

        self.customize_areas_dialog = PredefinedAreasDialog(self)
        self.customize_areas_dialog.setAttribute(Qt.WA_DeleteOnClose, True)
        self.customize_areas_dialog.show()

        def accepted():
            self.customize_areas_dialog = None

        def rejected():
            self.customize_areas_dialog = None

        self.customize_areas_dialog.accepted.connect(accepted)
        self.customize_areas_dialog.rejected.connect(rejected)


import time
import pytest
from aeon.measurement import Measurement
from aeon.errors import InvalidMeasurementState

def test_cant_start_measurement_twice():
    m = Measurement("name", "group")
    m.start()
    with pytest.raises(InvalidMeasurementState):
        m.start()

def test_cant_stop_measurement_before_starting_it():
    m = Measurement("name", "group")
    with pytest.raises(InvalidMeasurementState):
        m.stop()

def test_cant_stop_measurement_twice():
    m = Measurement("name", "group")
    m.start()
    m.stop()
    with pytest.raises(InvalidMeasurementState):
        m.stop()

def test_starting_measurement_increases_number_of_calls():
    m = Measurement("name", "group")
    assert m.calls == 0
    m.start()
    assert m.calls == 1

def test_measurement_measures_something():
    m = Measurement("name", "group")

    m.start()
    time.sleep(1e-3)
    m.stop()
    elapsed = m.total_runtime
    assert elapsed > 0

    m.start()
    time.sleep(1e-3)
    m.stop()
    elapsed_again = m.total_runtime
    assert elapsed_again > elapsed

@pytest.mark.fixed
def test_measurement_has_name_and_group():
    m = Measurement("name", "group")
    assert m.name == "name"
    assert m.group == "group"


#!/usr/bin/env python3
import sys

def hexdump(fileName):

#opens the specified file
 file = open(fileName)
#keep track of bytes away from the start of the file
 byteCount = -1
# a list to keep track of the current characters
 charList = []

#a loop that runs until the end of file is reached or exits if an error occurs
 while True:
  try:
   currentChar = file.read(1)
  except:
  	print ("Error:", sys.exc_info()[0])
  	sys.exit()

  #prints everything when the end of file is reached and then exits the loop
  if not currentChar:
   byteCount = byteCount + 1
   printByteNumber(byteCount)
   printHex(charList)
   printAscii(charList)
   charList = []
   #formatting purposes to show end of file was reached
   print ("%07x%x"%(byteCount,8))
   break

  #changes the character to a dot if it is not in range of printable characters
  if ord(currentChar) not in range(32,126):
   charList.append(".")
  else:
   charList.append(currentChar)

  #prints everything when 16 characters have been read in
  if len(charList) == 16:
   byteCount = byteCount + 1
   printByteNumber(byteCount)
   printHex(charList)
   printAscii(charList)
   charList = []

#prints the number of bytes since the start of the file as hex value
def printByteNumber(number):
	print ("%07x%x"%(number,0), end="  ")

#prints the hex values of all the characters in the list
def printHex(list):
	for x in range(0,len(list)):
	 #formatting the extra space between columns to match output, prints 00 for when a "." is found in the list
	 if x == 7 or x == 15:
	 	if list[x] == ".":
	 	  print("%02x"%0,end = "  ")
	 	else:
		  print ("%02x"%ord(list[x]), end ="  ")
	 else:
	 #formatting for when a "." is found in the list so it prints 00 instead of the hex value of a dot
	  if list[x] == ".":
	   print("%02x"%0,end = " ")
	 #prints regular hex value if not a "."
	  else:
	   print ("%02x"%ord(list[x]), end =" ")

	#formatiing for the end of the file if there are not 16 charcters in the list to make columns line up still
	if len(list) < 16:
	 for x in range(0,(16-len(list))):
	 	print("%s"%"  ", end = " ")
	 if len(list) < 8:
	  print(end = "  ")
	 else:
	  print(end = " ")

#prints the ascii of characters read with proper formatting
def printAscii(asciiList):
 print ("%s"%"|", end = "")
 for x in asciiList:
  print ("%s"%x, end = "")
 print ("%s"%"|")

#main method to run the hexdump taking in an argument from the command line
if __name__ == "__main__":
	hexdump(sys.argv[1])


import json
import logging
from decimal import Decimal
from typing import Dict, List, Optional, Type, Union

from enforce_typing import enforce_types
from web3.datastructures import AttributeDict

from ocean_lib.config import Config
from ocean_lib.data_provider.data_service_provider import DataServiceProvider
from ocean_lib.models.bpool import BPool
from ocean_lib.models.dispenser import Dispenser
from ocean_lib.models.erc20_token import ERC20Token
from ocean_lib.models.erc721_factory import ERC721FactoryContract
from ocean_lib.models.erc721_nft import ERC721NFT
from ocean_lib.models.factory_router import FactoryRouter
from ocean_lib.models.fixed_rate_exchange import FixedRateExchange
from ocean_lib.ocean.ocean_assets import OceanAssets
from ocean_lib.ocean.ocean_compute import OceanCompute
from ocean_lib.ocean.util import get_address_of_type, get_ocean_token_address, get_web3
from ocean_lib.web3_internal.constants import ZERO_ADDRESS
from ocean_lib.web3_internal.currency import DECIMALS_18
from ocean_lib.web3_internal.currency import to_wei as _to_wei
from ocean_lib.web3_internal.utils import split_signature
from ocean_lib.web3_internal.wallet import Wallet

logger = logging.getLogger("ocean")

class Ocean:
    """The Ocean class is the entry point into Ocean Protocol."""

    @enforce_types
    def __init__(
        self, config: Union[Dict, Config], data_provider: Optional[Type] = None
    ) -> None:
        """Initialize Ocean class.

        Usage: Make a new Ocean instance

        `ocean = Ocean({...})`

        This class provides the main top-level functions in ocean protocol:
        1. Publish assets metadata and associated services
            - Each asset is assigned a unique DID and a DID Document (DDO)
            - The DDO contains the asset's services including the metadata
            - The DID is registered on-chain with a URL of the metadata store
              to retrieve the DDO from

            `asset = ocean.assets.create(metadata, publisher_wallet)`

        2. Discover/Search assets via the current configured metadata store (Aquarius)

            - Usage:
            `assets_list = ocean.assets.search('search text')`

        An instance of Ocean is parameterized by a `Config` instance.

        :param config: `Config` instance
        :param data_provider: `DataServiceProvider` instance
        """
        if isinstance(config, dict):
            # fallback to metadataStoreUri
            cache_key = (
                "metadataCacheUri"
                if ("metadataCacheUri" in config)
                else "metadataStoreUri"
            )
            metadata_cache_uri = config.get(
                cache_key, config.get("metadata_cache_uri", "http://172.15.0.5:5000")
            )
            config_dict = {
                "eth-network": {"network": config.get("network", "")},
                "resources": {
                    "metadata_cache_uri": metadata_cache_uri,
                    "provider.url": config.get("providerUri", "http://172.15.0.4:8030"),
                },
            }
            config = Config(options_dict=config_dict)
        self.config = config
        self.web3 = get_web3(self.config.network_url)

        if not data_provider:
            data_provider = DataServiceProvider

        self.assets = OceanAssets(self.config, self.web3, data_provider)
        self.compute = OceanCompute(self.config, data_provider)

        logger.debug("Ocean instance initialized: ")

    @property
    @enforce_types
    def OCEAN_address(self) -> str:
        return get_ocean_token_address(self.config.address_file, web3=self.web3)

    @enforce_types
    def to_wei(
        self, amount_in_ether: Union[Decimal, str, int], decimals: int = DECIMALS_18
    ):
        return _to_wei(amount_in_ether=amount_in_ether, decimals=decimals)

    @enforce_types
    def create_erc721_nft(
        self,
        name: str,
        symbol: str,
        from_wallet: Wallet,
        token_uri: Optional[str] = "https://oceanprotocol.com/nft/",
        template_index: Optional[int] = 1,
        additional_erc20_deployer: Optional[str] = None,
        additional_metadata_updater: Optional[str] = None,
    ) -> ERC721NFT:
        """
        This method deploys a ERC721 token contract on the blockchain.
        Usage:
        ```python
            config = Config('config.ini')
            ocean = Ocean(config)
            wallet = Wallet(
                ocean.web3,
                private_key=private_key,
                block_confirmations=config.block_confirmations,
                transaction_timeout=config.transaction_timeout,
            )
            erc721_nft = ocean.create_erc721_nft("Dataset name", "dtsymbol", from_wallet=wallet)
        ```
        :param name: ERC721 token name, str
        :param symbol: ERC721 token symbol, str
        :param from_wallet: wallet instance, wallet
        :param template_index: Template type of the token, int
        :param additional_erc20_deployer: Address of another ERC20 deployer, str
        :param token_uri: URL for ERC721 token, str

        :return: `ERC721NFT` instance
        """

        if not additional_erc20_deployer:
            additional_erc20_deployer = ZERO_ADDRESS

        if not additional_metadata_updater:
            additional_metadata_updater = ZERO_ADDRESS

        nft_factory = self.get_nft_factory()
        tx_id = nft_factory.deploy_erc721_contract(
            name=name,
            symbol=symbol,
            template_index=template_index,
            additional_metadata_updater=additional_metadata_updater,
            additional_erc20_deployer=additional_erc20_deployer,
            token_uri=token_uri,
            from_wallet=from_wallet,
        )

        address = nft_factory.get_token_address(tx_id)
        assert address, "new NFT token has no address"
        token = ERC721NFT(self.web3, address)
        return token

    @enforce_types
    def get_nft_token(self, token_address: str) -> ERC721NFT:
        """
        :param token_address: Token contract address, str
        :return: `ERC721NFT` instance
        """

        return ERC721NFT(self.web3, token_address)

    @enforce_types
    def get_datatoken(self, token_address: str) -> ERC20Token:
        """
        :param token_address: Token contract address, str
        :return: `ERC20Token` instance
        """

        return ERC20Token(self.web3, token_address)

    @enforce_types
    def get_nft_factory(self, nft_factory_address: str = "") -> ERC721FactoryContract:
        """
        :param nft_factory_address: contract address, str

        :return: `ERC721FactoryContract` instance
        """
        if not nft_factory_address:
            nft_factory_address = get_address_of_type(
                self.config, ERC721FactoryContract.CONTRACT_NAME
            )

        return ERC721FactoryContract(self.web3, nft_factory_address)

    @enforce_types
    def get_user_orders(
        self, address: str, datatoken: Optional[str] = None
    ) -> List[AttributeDict]:
        """
        :return: List of orders `[Order]`
        """
        dt = ERC20Token(self.web3, datatoken)
        _orders = []
        for log in dt.get_start_order_logs(
            address, from_all_tokens=not bool(datatoken)
        ):
            a = dict(log.args.items())
            a["amount"] = int(log.args.amount)
            a["address"] = log.address
            a["transactionHash"] = log.transactionHash
            a = AttributeDict(a.items())

            _orders.append(a)

        return _orders

    @property
    @enforce_types
    def dispenser(self):
        return Dispenser(self.web3, get_address_of_type(self.config, "Dispenser"))

    @property
    @enforce_types
    def fixed_rate_exchange(self):
        return FixedRateExchange(
            self.web3, get_address_of_type(self.config, "FixedPrice")
        )

    @enforce_types
    def create_fixed_rate(
        self,
        erc20_token: ERC20Token,
        base_token: ERC20Token,
        amount: int,
        from_wallet: Wallet,
    ) -> bytes:
        fixed_price_address = get_address_of_type(self.config, "FixedPrice")
        erc20_token.approve(fixed_price_address, amount, from_wallet)

        tx = erc20_token.create_fixed_rate(
            fixed_price_address=fixed_price_address,
            base_token_address=base_token.address,
            owner=from_wallet.address,
            publish_market_swap_fee_collector=from_wallet.address,
            allowed_swapper=ZERO_ADDRESS,
            base_token_decimals=base_token.decimals(),
            datatoken_decimals=erc20_token.decimals(),
            fixed_rate=self.to_wei(1),
            publish_market_swap_fee_amount=int(1e15),
            with_mint=0,
            from_wallet=from_wallet,
        )
        tx_receipt = self.web3.eth.wait_for_transaction_receipt(tx)
        fixed_rate_event = erc20_token.get_event_log(
            ERC721FactoryContract.EVENT_NEW_FIXED_RATE,
            tx_receipt.blockNumber,
            self.web3.eth.block_number,
            None,
        )
        exchange_id = fixed_rate_event[0].args.exchangeId

        return exchange_id

    @property
    @enforce_types
    def factory_router(self):
        return FactoryRouter(self.web3, get_address_of_type(self.config, "Router"))

    @enforce_types
    def create_pool(
        self,
        erc20_token: ERC20Token,
        base_token: ERC20Token,
        rate: int,
        vesting_amount: int,
        vesting_blocks: int,
        base_token_amount: int,
        lp_swap_fee_amount: int,
        publish_market_swap_fee_amount: int,
        from_wallet: Wallet,
    ) -> BPool:
        base_token.approve(
            get_address_of_type(self.config, "Router"), self.to_wei("2000"), from_wallet
        )

        tx = erc20_token.deploy_pool(
            rate=rate,
            base_token_decimals=base_token.decimals(),
            vesting_amount=vesting_amount,
            vesting_blocks=vesting_blocks,
            base_token_amount=base_token_amount,
            lp_swap_fee_amount=lp_swap_fee_amount,
            publish_market_swap_fee_amount=publish_market_swap_fee_amount,
            ss_contract=get_address_of_type(self.config, "Staking"),
            base_token_address=base_token.address,
            base_token_sender=from_wallet.address,
            publisher_address=from_wallet.address,
            publish_market_swap_fee_collector=get_address_of_type(
                self.config, "OPFCommunityFeeCollector"
            ),
            pool_template_address=get_address_of_type(self.config, "poolTemplate"),
            from_wallet=from_wallet,
        )
        tx_receipt = self.web3.eth.wait_for_transaction_receipt(tx)
        pool_event = self.factory_router.get_event_log(
            ERC721FactoryContract.EVENT_NEW_POOL,
            tx_receipt.blockNumber,
            self.web3.eth.block_number,
            None,
        )

        bpool_address = pool_event[0].args.poolAddress
        bpool = BPool(self.web3, bpool_address)

        return bpool

    @enforce_types
    def build_compute_provider_fees(
        self,
        provider_data: Union[str, dict],
        provider_fee_address: str,
        provider_fee_token: str,
        provider_fee_amount: int,
        valid_until: int,
    ) -> tuple:
        if isinstance(provider_data, dict):
            provider_data = json.dumps(provider_data, separators=(",", ":"))

        message = self.web3.solidityKeccak(
            ["bytes", "address", "address", "uint256", "uint256"],
            [
                self.web3.toHex(self.web3.toBytes(text=provider_data)),
                provider_fee_address,
                provider_fee_token,
                provider_fee_amount,
                valid_until,
            ],
        )
        signed = self.web3.eth.sign(provider_fee_address, data=message)
        signature = split_signature(signed)

        return (
            signature.v,
            signature.r,
            signature.s,
            self.web3.toHex(self.web3.toBytes(text=provider_data)),
        )


"""new_eac_schema_payment
"""
from alembic import op
import sqlalchemy as sa

# pre/post deployment: pre
# revision identifiers, used by Alembic.
revision = "a7accb2d29db"
down_revision = "801ba453e407"
branch_labels = None
depends_on = None

def upgrade() -> None:
    op.add_column("payment", sa.Column("collectiveBookingId", sa.BigInteger(), nullable=True))
    op.alter_column("payment", "bookingId", existing_type=sa.BIGINT(), nullable=True)
    op.create_index(op.f("ix_payment_collectiveBookingId"), "payment", ["collectiveBookingId"], unique=False)
    op.create_foreign_key(
        "payment_collective_booking_fk", "payment", "collective_booking", ["collectiveBookingId"], ["id"]
    )

def downgrade() -> None:
    op.drop_constraint("payment_collective_booking_fk", "payment", type_="foreignkey")
    op.drop_index(op.f("ix_payment_collectiveBookingId"), table_name="payment")
    op.alter_column("payment", "bookingId", existing_type=sa.BIGINT(), nullable=False)
    op.drop_column("payment", "collectiveBookingId")


from clients.python import TaskService_v1
from clients.python.protos.sylklabs.Todos.v1.Todos_pb2 import TaskId
import grpc

client = TaskService_v1(
    client_opt={
        'host': 'localhost',
        'port': 51010
    }
)

try:
    task = client.GetTask(TaskId(id='1'))
    print(task)
# Custom handling of exceptions
except grpc.RpcError as rpc_error:
    if rpc_error.code() == grpc.StatusCode.NOT_FOUND:
        print(f"Received RPC error: code={rpc_error.code()} message={rpc_error.details()}")
    else:
        print(f"Received unknown RPC error: code={rpc_error.code()} message={rpc_error.details()}")


from django.urls import path
from . import views
from django.conf.urls import url

urlpatterns = [
path('', views.index, name='index'),
path('series', views.series, name='series'),
path('free_episodes', views.free_episodes, name='free_episodes'),
path('gethbo', views.gethbo, name='gethbo'),
path('blog', views.post_list, name='post_list'),

	# path('main', views.main, name='main'),

]


from flask import render_template, flash, redirect, url_for, request
from flask_login import current_user, login_required
from app import db
from datetime import datetime
from .models import *
from .forms import *
from app.stock.models import Company
from app.account_manage.models import User,Admin
from app.balance import balance_bp

#股权列表
@balance_bp.route('/allstockown')
@login_required
def allStockOwn():
    page = int(request.args.get('page', 1))             #当前页
    per_page = int(request.args.get('per_page', 5))     #每页条数
    paginate2 = StockOwn.query.filter(StockOwn.user_id==current_user.user_id).order_by(StockOwn.company_id.asc()).paginate(page, per_page, error_out = False)
    stock_own_list = paginate2.items
    #加上公司名称和股价
    stockown_with_info = []
    for stockown in stock_own_list:
        new_stockown = {}
        new_stockown['company_id'] = stockown.company_id
        company = Company.query.filter(Company.company_id == stockown.company_id).first()
        new_stockown['company_name'] = company.company_name
        new_stockown['price'] = company.price
        new_stockown['amount']=stockown.amount
        stockown_with_info.append(new_stockown)
    return render_template("allstockown.html",
                           title='股权列表',
                           stock_own_list = stockown_with_info,
                           pagination = paginate2)

#充值
@balance_bp.route('/charge', methods = ['GET','POST'])
@login_required
def charge():
    form = ChargeForm()
    if form.validate_on_submit():
        #点击充值
        if form.submit.data:
            amount = form.amount.data
            if amount<=0:
                flash('金额错误')
            else:
                user=User.query.filter(User.user_id==current_user.user_id).first()
                user.balance+=amount
                #db.session.add(notice)
                #获取自增的Post_ID
                #db.session.flush()
                #notice_id = notice.Notice_ID
                db.session.commit()
                flash('充值成功')
                #跳转到账户页面
                return redirect(url_for('account.myinfo',info_action='checkdetail'))
        #点击取消
        else:
            flash('充值已取消')
            #跳转到账户页面
            return redirect(url_for('account.myinfo',info_action='checkdetail'))
    return render_template("charge.html",
                           title='充值',
                           form = form)


import re

GTIN_MATCH = re.compile(r'^\d{8}$|^\d{12,14}$')

def calc_check_digit(upc_string):
    evens = []
    odds = []

    for i, char in enumerate(upc_string):
        if (i + 2) % 2 == 0:
            evens.append(int(char))
        else:
            odds.append(int(char))

    return (10 - (((3 * sum(evens)) + sum(odds)) % 10)) % 10

def is_valid_upc(upc_string):
    match = GTIN_MATCH.match(upc_string)

    if not match:
        return False

    return calc_check_digit(upc_string[:-1]) == int(upc_string[-1])


"""
Simple function to find the maximum value in a list of numbers
"""

def findMax(listToSearch):
    max = 0
    for d in listToSearch:
        if(d>max):
            max=d
    return max

# main method to test our function

def main():
    testList = [1,23,52,27,54,3,78,3,4,36,22,236,22358,235683,38,1]
    print("Maximum value in " + str(testList) + " is " + str(findMax((testList))))

main()


from django.forms import *
from .models import Category

class CategoryForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # for form in self.visible_fields():
        #     form.field.widget.attrs['class'] = 'form-control'
        #     form.field.widget.attrs['autocomplete'] = 'off'
        self.fields['name'].widget.attrs['autofocus'] = True

    class Meta:
        model = Category
        fields = '__all__'
        widgets = {
            'name': TextInput(
                attrs={
                    'placeholder': 'Ingrese el nombre de la categoria',
                }
            ),
            'desc': Textarea(
                attrs={
                    'placeholder': 'Ingrese una descripción de la categoria',
                    'rows': 3,
                    'cols': 3
                }
            ),
        }
    def save(self, commit=True):
        data = {}
        form = super()
        try:
            if form.is_valid():
                form.save()
            else:
                data['error'] = form.errors
        except Exception as e:
            data['error'] = str(e)
        return data

    """def clean(self):
        cleaned = super().clean()
        if len(cleaned['name'])<=50:
            raise forms.ValidationError('Name error')
        return cleaned"""


import sys
import math
from fractions import Fraction
from typing import Dict, List

class Vector:
    def __init__(self, x: Fraction, y: Fraction):
        self.x = x
        self.y = y

    @staticmethod
    def from_str(s: str):
        x, y = s.split(',')
        return Vector(Fraction(x), Fraction(y))

    def __repr__(self):
        return "Vector(" + str(self.x) + ', ' + str(self.y) + ")"

    def __str__(self):
        return str(self.x) + ',' + str(self.y)

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

    def __lt__(self, other):
        return self.x < other.x or (self.x == other.x and self.y < other.y)

    def __hash__(self):
        return (self.x, self.y).__hash__()

class Segment:
    def __init__(self, p0: Vector, p1: Vector):
        self.p0 = p0
        self.p1 = p1

    def __repr__(self):
        return "Segment(" + repr(self.p0) + ', ' + repr(self.p1) + ")"

class Polygon:
    def __init__(self, points: List[Vector]):
        self.points = points
        self.segments = [Segment(p0, p1) for p0, p1 in zip(points, points[1:] + points[:1])]

    def __repr__(self):
        return "Polygon(" + repr(self.points) + ")"

class Problem:
    def __init__(self):
        #: :type: List[Polygon]
        self.polygons = []
        #: :type: List[Segment]
        self.segments = []

    def load(self, filename):
        with open(filename) as f:
            num_polygons = int(f.readline())
            for _ in range(num_polygons):
                num_vertices = int(f.readline())
                self.polygons.append(Polygon([Vector.from_str(f.readline()) for _ in range(num_vertices)]))
            num_segments = int(f.readline())
            for _ in range(num_segments):
                p0, p1 = (Vector.from_str(x) for x in f.readline().split(' '))
                self.segments.append(Segment(p0, p1))

def intersect(s: Segment, t: Segment):
    sx = s.p1.x - s.p0.x
    sy = s.p1.y - s.p0.y
    tx = t.p1.x - t.p0.x
    ty = t.p1.y - t.p0.y
    cross = sx * ty - sy * tx
    if cross == Fraction(0):
        return None
    ux = t.p0.x - s.p0.x
    uy = t.p0.y - s.p0.y
    a = (ux * ty - uy * tx) / cross
    b = (ux * sy - uy * sx) / cross
    if Fraction(0) < a < Fraction(1) and Fraction(0) < b < Fraction(1):
        return Vector(a * sx + s.p0.x, a * sy + s.p0.y)
    return None

def position(s: Segment, p: Vector):
    x0, y0 = s.p0.x, s.p0.y
    x1, y1 = s.p1.x, s.p1.y
    x2, y2 = p.x, p.y
    sx = x0 - x2
    tx = x1 - x2
    sy = y0 - y2
    ty = y1 - y2
    cross = sx * ty - sy * tx
    if cross != Fraction(0):
        return None
    dot = sx * tx + sy * ty
    if dot > Fraction(0):
        return None
    if x0 != x1:
        return (x2 - x0) / (x1 - x0)
    else:
        return (y2 - y0) / (y1 - y0)

class Vertices:
    def __init__(self, p: Problem):
        points = set()
        for x in p.polygons:
            for y in x.points:
                points.add(y)
        for x in p.segments:
            points.add(x.p0)
            points.add(x.p1)
            for y in p.segments:
                p2 = intersect(x, y)
                if p2 is not None:
                    points.add(p2)
        #: :type: List[Vector]
        self.v_list = sorted(points)
        #: :type: Dict[Vector, int]
        self.v_dict = {x: i for i, x in enumerate(self.v_list)}

class Graph:
    def __init__(self, p: Problem, v: Vertices):
        self.p = p
        self.v = v
        self.G = {i: set() for i in range(len(v.v_list))}
        self.e_polygon = set()
        self.area_idx_dict = {}
        self.areas = []
        self.painted = {}

    def add_segment(self, s: Segment, is_polygon: bool):
        a = []
        for k, v in enumerate(self.v.v_list):
            p = position(s, v)
            if p is not None:
                a.append((p, k))
        b = [x[1] for x in sorted(a)]
        for s, t in zip(b, b[1:]):
            self.G[s].add(t)
            self.G[t].add(s)
            if is_polygon:
                self.e_polygon.add((s, t))

    def visit(self, p, q, area_idx):
        self.area_idx_dict[(p, q)] = area_idx
        if q in self.areas[area_idx]:
            return
        self.areas[area_idx].append(q)
        # todo 有理数化
        min_c = 2
        max_c = -2
        selected_r = None
        for r in self.G[q]:
            if p != r:
                vp = self.v.v_list[p]
                vq = self.v.v_list[q]
                vr = self.v.v_list[r]
                sx = vq.x - vp.x
                sy = vq.y - vp.y
                tx = vr.x - vq.x
                ty = vr.y - vq.y
                crs = sx * ty - sy * tx
                c = (sx * tx + sy * ty) / math.sqrt(sx * sx + sy * sy) / math.sqrt(tx * tx + ty * ty)
                if crs >= Fraction(0):
                    if c < min_c:
                        min_c = c
                        selected_r = r
                elif min_c == 2:
                    if c > max_c:
                        max_c = c
                        selected_r = r
        self.visit(q, selected_r, area_idx)

    def paint(self, area_idx, is_inside):
        if area_idx in self.painted:
            assert self.painted[area_idx] == is_inside
            return
        self.painted[area_idx] = is_inside
        area = self.areas[area_idx]
        for s, t in zip(area, area[1:] + area[:1]):
            if (s, t) not in self.e_polygon and (t, s) not in self.e_polygon:
                next_area_idx = self.area_idx_dict[(t, s)]
                self.paint(next_area_idx, is_inside)

    def build_area(self):
        for x in self.p.polygons:
            for y in x.segments:
                self.add_segment(y, True)
        for x in self.p.segments:
            self.add_segment(x, False)

        for i in range(len(self.G)):
            for j in sorted(self.G[i]):
                if (i, j) not in self.area_idx_dict:
                    area_idx = len(self.areas)
                    self.areas.append([i])
                    self.visit(i, j, area_idx)

        for s, t in self.e_polygon:
            area_idx_i = self.area_idx_dict[(s, t)]
            area_idx_o = self.area_idx_dict[(t, s)]
            self.paint(area_idx_i, True)
            self.paint(area_idx_o, False)

    def print(self):
        print(len(self.v.v_list))
        for v in self.v.v_list:
            print(str(v))

        res = []
        for idx, area in enumerate(self.areas):
            if self.painted[idx]:
                res.append(' '.join(str(x) for x in area))
        print(len(res))
        for x in res:
            print(x)

def main():
    problem = Problem()
    problem.load(sys.argv[1])
    vertices = Vertices(problem)
    graph = Graph(problem, vertices)
    graph.build_area()
    graph.print()

main()


import sys
from collections import deque

read = sys.stdin.readline

n, m = map(int, read().split())
graph = [read().split() for _ in range(n)]
dist = [[0] * m for _ in range(n)]
res = 0

q = deque()
for i in range(n):
    for j in range(m):
        if graph[i][j] == '1':
            q.append((i, j))

while q:
    x, y = q.popleft()
    for i in range(-1, 2):
        for j in range(-1, 2):
            if i == j == 0: continue
            nx, ny = x + i, y + j
            if 0 <= nx < n and 0 <= ny < m and \
                graph[nx][ny] == '0' and dist[nx][ny] == 0:
                dist[nx][ny] = dist[x][y] + 1
                q.append((nx, ny))

for l in dist:
    res = max(res, max(l))
print(res)


print('\033[1;46m{:=^40}\033[m'.format(' LOJAS HUGO '))
normal = float(input('Qual é o valor das suas compras? R$'))
condição = int(input('''FORMAS DE PAGAMENTO:
[ 1 ] à vista no dinheiro
[ 2 ] a vista no cartão
[ 3 ] 2x no cartão
[ 4 ] 3x ou mais no cartão
Qual é a opção?'''))
if condição ==1:
    p = normal*.9
    print('À vista no dinheiro o valor cai de R${:.2f} para R${:.2f} com 10% de desconto.'.format(normal, p))
elif condição ==2:
    p = normal*.95
    print('À vista no cartão o valor cai de R${:.2f} para R${:.2f} com 5% de desconto.'.format(normal, p))
elif condição ==3:
    p = normal
    print('Em até 2x no cartão o preço é o mesmo de R${:.2f}'.format(p))
elif condição ==4:
    p = normal*1.2
    totparc = int(input('Quantas parcelas?'))
    parcela = p/totparc
    print('Sua compra será efetuada em {} parcelas de R${}'.format(totparc, parcela))
    print('Em 3x ou mais no cartão o valor passa de R${:.2f} para R${:.2f} com 20% de juros.'.format(normal, p))
else:
    print('Opção inválida. Tente novamente.')


from PyQt5.QtCore import QThread, pyqtSignal
import threading
import time
from program import MainProgram

# Model: pengkoneksi UI dengan program aslinya
class Model:
    def __init__(self):
        self.size = 4
        self.bombs = 0
        self.bombLoc = []
        self.program = None
        self.updater = None
        self.programThread = None
        self.printToUi = None

    def startAI(self):
        self.program = MainProgram()
        self.program.ukuran = self.size
        self.program.jumlah_bom = self.bombs
        self.program.bombLoc = self.bombLoc
        self.program.printToUI = self.printToUi
        self.programThread = threading.Thread(
            target=self.program.main
        )
        self.programThread.start()
        self.updater = checkFromProgram(self)

class checkFromProgram(QThread):
    progress = pyqtSignal(list)

    def __init__(self, model):
        super().__init__()
        self.model = model

    def run(self):
        print("run")
        while self.model.program.is_finished == 0:
            time.sleep(0.1)
        print("setup finished")
        while not self.model.program.is_finished == 2:
            time.sleep(0.2)
            self.progress.emit(self.model.program.updatePapanBasedOnFacts())


#!/usr/bin/python3.2

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.post()

    def post(self):
        raise tornado.web.HTTPError(403)

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()


import os
import json
from typing import Union, List, Dict

import transformers
import torch
from tqdm.auto import tqdm

from . import utils
from .utils import _infer_model_family, _infer_model_or_path

def _select_device(device_selection):
    selected = device_selection.lower()
    if selected == "auto":
        device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    elif selected == "cpu":
        device = torch.device("cpu")
    elif selected == "gpu":
        device = torch.device("cuda")
    else:
        device = torch.device(selected)

    return device

def _resolve_lang_codes(lang: str, name: str, model_family: str):
    def error_message(variable, value):
        return f'Your {variable}="{value}" is not valid. Please run `print(mt.available_languages())` to see which languages are available. Make sure you are using the correct capital letters.'

    # If can't find in the lang -> code mapping, assumes it's already a code.
    lang_code_map = utils.get_lang_code_map(model_family)
    if lang in lang_code_map:
        code = lang_code_map[lang]
    elif lang.capitalize() in lang_code_map:
        code = lang_code_map[lang.capitalize()]
    else:
        lang_upper = lang.upper()
        lang_code_map_upper = {k.upper(): v for k, v in lang_code_map.items()}

        if lang_upper in lang_code_map_upper:
            code = lang_code_map_upper[lang_upper]
        else:
            code = lang

    # If the code is not valid, raises an error
    if code not in utils.available_codes(model_family):
        raise ValueError(error_message(name, code))

    return code

def _resolve_tokenizer(model_family):
    di = {
        "mbart50": transformers.MBart50TokenizerFast,
        "m2m100": transformers.M2M100Tokenizer,
        "nllb200": transformers.AutoTokenizer,
    }
    if model_family in di:
        return di[model_family]
    else:
        error_msg = f"{model_family} is not a valid value for model_family. Please choose model_family to be equal to one of the following values: {list(di.keys())}"
        raise ValueError(error_msg)

def _resolve_transformers_model(model_family):
    di = {
        "mbart50": transformers.MBartForConditionalGeneration,
        "m2m100": transformers.M2M100ForConditionalGeneration,
        "nllb200": transformers.AutoModelForSeq2SeqLM,
    }
    if model_family in di:
        return di[model_family]
    else:
        error_msg = f"{model_family} is not a valid value for model_family. Please choose model_family to be equal to one of the following values: {list(di.keys())}"
        raise ValueError(error_msg)

class TranslationModel:
    def __init__(
        self,
        model_or_path: str = "m2m100",
        tokenizer_path: str = None,
        device: str = "auto",
        model_family: str = None,
        model_options: dict = None,
        tokenizer_options: dict = None,
    ):
        """
        *Instantiates a multilingual transformer model for translation.*

        {{params}}
        {{model_or_path}} The path or the name of the model. Equivalent to the first argument of `AutoModel.from_pretrained()`. You can also specify shorthands ("mbart50" and "m2m100").
        {{tokenizer_path}} The path to the tokenizer. By default, it will be set to `model_or_path`.
        {{device}} "cpu", "gpu" or "auto". If it's set to "auto", will try to select a GPU when available or else fall back to CPU.
        {{model_family}} Either "mbart50" or "m2m100". By default, it will be inferred based on `model_or_path`. Needs to be explicitly set if `model_or_path` is a path.
        {{model_options}} The keyword arguments passed to the model, which is a transformer for conditional generation.
        {{tokenizer_options}} The keyword arguments passed to the model's tokenizer.
        """
        model_or_path = _infer_model_or_path(model_or_path)
        self.model_or_path = model_or_path
        self.device = _select_device(device)

        # Resolve default values
        tokenizer_path = tokenizer_path or self.model_or_path
        model_options = model_options or {}
        tokenizer_options = tokenizer_options or {}
        self.model_family = model_family or _infer_model_family(model_or_path)

        # Load the tokenizer
        TokenizerFast = _resolve_tokenizer(self.model_family)
        self._tokenizer = TokenizerFast.from_pretrained(
            tokenizer_path, **tokenizer_options
        )

        # Load the model either from a saved torch model or from transformers.
        if model_or_path.endswith(".pt"):
            self._transformers_model = torch.load(
                model_or_path, map_location=self.device
            ).eval()
        else:
            ModelForConditionalGeneration = _resolve_transformers_model(
                self.model_family
            )
            self._transformers_model = (
                ModelForConditionalGeneration.from_pretrained(
                    self.model_or_path, **model_options
                )
                .to(self.device)
                .eval()
            )

    def translate(
        self,
        text: Union[str, List[str]],
        source: str,
        target: str,
        batch_size: int = 32,
        verbose: bool = False,
        generation_options: dict = None,
    ) -> Union[str, List[str]]:
        """
        *Translates a string or a list of strings from a source to a target language.*

        {{params}}
        {{text}} The content you want to translate.
        {{source}} The language of the original text.
        {{target}} The language of the translated text.
        {{batch_size}} The number of samples to load at once. If set to `None`, it will process everything at once.
        {{verbose}} Whether to display the progress bar for every batch processed.
        {{generation_options}} The keyword arguments passed to `model.generate()`, where `model` is the underlying transformers model.

        Note:
        - Run `print(dlt.utils.available_languages())` to see what's available.
        - A smaller value is preferred for `batch_size` if your (video) RAM is limited.
        """
        if generation_options is None:
            generation_options = {}

        source = _resolve_lang_codes(source, "source", self.model_family)
        target = _resolve_lang_codes(target, "target", self.model_family)

        self._tokenizer.src_lang = source

        original_text_type = type(text)
        if original_text_type is str:
            text = [text]

        if batch_size is None:
            batch_size = len(text)

        generation_options.setdefault(
            "forced_bos_token_id", self._tokenizer.lang_code_to_id[target]
        )
        generation_options.setdefault("max_new_tokens", 512)

        data_loader = torch.utils.data.DataLoader(text, batch_size=batch_size)
        output_text = []

        with torch.no_grad():
            for batch in tqdm(data_loader, disable=not verbose):
                encoded = self._tokenizer(batch, return_tensors="pt", padding=True)
                encoded.to(self.device)

                generated_tokens = self._transformers_model.generate(
                    **encoded, **generation_options
                ).cpu()

                decoded = self._tokenizer.batch_decode(
                    generated_tokens, skip_special_tokens=True
                )

                output_text.extend(decoded)

        # If text: str and output_text: List[str], then we should convert output_text to str
        if original_text_type is str and len(output_text) == 1:
            output_text = output_text[0]

        return output_text

    def get_transformers_model(self):
        """
        *Retrieve the underlying mBART transformer model.*
        """
        return self._transformers_model

    def get_tokenizer(self):
        """
        *Retrieve the mBART huggingface tokenizer.*
        """
        return self._tokenizer

    def available_languages(self) -> List[str]:
        """
        *Returns all the available languages for a given `dlt.TranslationModel`
        instance.*
        """
        return utils.available_languages(self.model_family)

    def available_codes(self) -> List[str]:
        """
        *Returns all the available codes for a given `dlt.TranslationModel`
        instance.*
        """
        return utils.available_codes(self.model_family)

    def get_lang_code_map(self) -> Dict[str, str]:
        """
        *Returns the language -> codes dictionary for a given `dlt.TranslationModel`
        instance.*
        """
        return utils.get_lang_code_map(self.model_family)

    def save_obj(self, path: str = "saved_model") -> None:
        """
        *Saves your model as a torch object and save your tokenizer.*

        {{params}}
        {{path}} The directory where you want to save your model and tokenizer
        """
        os.makedirs(path, exist_ok=True)
        torch.save(self._transformers_model, os.path.join(path, "weights.pt"))
        self._tokenizer.save_pretrained(path)

        dlt_config = dict(model_family=self.model_family)
        json.dump(dlt_config, open(os.path.join(path, "dlt_config.json"), "w"))

    @classmethod
    def load_obj(cls, path: str = "saved_model", **kwargs):
        """
        *Initialize `dlt.TranslationModel` from the torch object and tokenizer
        saved with `dlt.TranslationModel.save_obj`*

        {{params}}
        {{path}} The directory where your torch model and tokenizer are stored
        """
        config_prev = json.load(open(os.path.join(path, "dlt_config.json"), "rb"))
        config_prev.update(kwargs)
        return cls(
            model_or_path=os.path.join(path, "weights.pt"),
            tokenizer_path=path,
            **config_prev,
        )


def leer():

    cad = input("ingrese matriz separando filas por ; y columnas por , ")

    filas = cad.split(',')

    for i in range(len(filas)):
        filas[i] =  filas[i].split(',')
    for i in range(len(filas)):
        for j in range(len(filas[i])):
            filas[i][j] = float(filas[i][j])

def imprimir(A):
  for i in range(len(A)):
    print('|', end=' ')
    for j in range(len(A[i])):
      print(A[i][j], end=' ')
    print('|')

def multiplica(A,B):

    c = []
    n = len(A)
    m = len(A[0])
    l = len(B[0])

    for i in range(n):
        c.append([])
        for j in range(l):
            s=0
            for k in range(m):
                s+= A[i][k]*B[k][j]
            c[i].append(s)
    return imprimir(c)

a = [[3,4],[6,8],[2,1]]
b = [[2,6],[4,3]]

z = multiplica(a,b)

print(z)

Problemas de programacion/51--70/51 matrices.py


from typing import Type, TypeVar, List, Optional
from sqlalchemy import and_, select
from sqlalchemy.ext.asyncio import AsyncSession

from core.database import Base

ModelType = TypeVar('ModelType', bound=Base)

class BaseRepository:
    '''Base Data Repository'''

    def __init__(self, model: Type[ModelType], session: AsyncSession):
        self.model_class = model
        self.session = session

    async def create(self, **attributes) -> ModelType:
        '''
        Create a new model instance.
        :param attributes: the data for creating object
        :return: The created object.
        '''

        model = self.model_class(**attributes)
        self.session.add(model)
        await self.session.commit()
        return model

    async def update(self, model: ModelType, **update_data) -> ModelType:
        """
        Updates the given model instance with the given data.

        :param model: The model instance to update.
        :param update_data: A dictionary containing the new data to update
        the model with.
        :return: The updated model instance.
        """

        for key, value in update_data.items():
            setattr(model, key, value)

        self.session.add(model)
        await self.session.commit()
        return model

    async def delete(self, model: ModelType) -> None:
        """
        Deletes the model instance.

        :param model: The model to delete.
        :return: None
        """
        await self.session.delete(model)
        await self.session.commit()

    async def get_all(self, limit: int = 20, **kwargs) -> List[ModelType]:
        """
        Retrieves all model instances that match the specified criteria.

        :param limit: The maximum number of results to return.
        :param kwargs: Filter criteria.
        :return: A list of model instances, up to the specified limit.
        """
        query = await self._get_base_query(limit=limit, **kwargs)
        result = await self.session.execute(query)
        return result.all()

    async def get_one(self, **kwargs) -> Optional[ModelType]:
        """
        Retrieves the first model instance that matches the specified criteria.

        :param limit: The maximum number of results to return.
        :param kwargs: Filter criteria.
        :return: The model instance that matches the specified criteria,
        or None if not found.
        """
        query = await self._get_base_query(limit=1, **kwargs)
        result = await self.session.execute(query)
        model_id = result.scalars().first()
        if not model_id:
            return

        model = await self.session.get(self.model_class, model_id)
        return model

    async def _get_base_query(self, limit: int = None, **kwargs):
        """
        Constructs a base query object based on the specified filter criteria
        and limit.

        :param limit: The maximum number of results to return.
        :param kwargs: Filter criteria.
        :return: A base query object.
        """
        table = self.model_class.__table__
        query = select(table)
        filters = [
            table.columns[field] == value for field, value in kwargs.items()
        ]
        if filters:
            query = query.where(and_(*filters))
        if limit is not None:
            query = query.limit(limit)
        return query