import pandas as pd
import geopandas as gpd
from shapely.geometry import Point, LineString
from .utils import report_progress
from .lsm import snap_to_waterbodies
import warnings

def get_dm_nodes(dw_keys_df, district, mz_type ="d", out_type=int):
    df = dw_keys_df[dw_keys_df.oid == district]
    dm_nodes = [out_type(i) for i in df[df.kty == mz_type].nid.unique()]
    return dm_nodes

def find_unique_dm_links(
        lsw_nodes_gdf: gpd.GeoDataFrame,
        dw_keys_df: pd.DataFrame,
        mz_type ="d") -> list:
    """Finding unique DM nodes."""
    lsw_dm_links = []
    for dw, df in dw_keys_df.groupby(by=["oid"]):
        dm_nodes = df.loc[df.kty == mz_type].nid.unique()
        if len(dm_nodes) == 1:
            df = lsw_nodes_gdf[lsw_nodes_gdf["DWRN"] == dw]
            for row in df.itertuples():
                lsw_dm_links += [(row.LSWFINAL, dm_nodes[0])]
    return lsw_dm_links

def find_routing_to_dm_links(
        lsw_nodes_gdf: gpd.GeoDataFrame,
        lsw_gdf: gpd.GeoDataFrame,
        dw_keys_df: pd.DataFrame,
        lkm_links_gdf: gpd.GeoDataFrame,
        lsm_lhm_gdf: gpd.GeoDataFrame,
        lkm_waterlichamen_gdf: gpd.GeoDataFrame,
        ) -> list:

    warnings.simplefilter(action='ignore', category=UserWarning)
    # algemene functie om links te vinden mbv een LKM link
    def find_links(row, lsw_id):
        lsw_dm_links = []
        polygon = lsw_gdf.at[lsw_id, "geometry"]
        df = lsm_lhm_gdf[lsm_lhm_gdf.within(polygon)]# we kijken of er lateralen in het gebied van de LSW liggen

        if not df.empty:
            lsw_dm_links +=[(lsw_id, i) for i in df.DM.unique()]

        if row.nodeto.startswith("LSM"): # de link moet starten met LSM
            point = Point(row.geometry.bounds[2:]) # de Point van de nodeto
            waterlichaam_gdf = lkm_waterlichamen_gdf[lkm_waterlichamen_gdf.intersects(point)] # het waterlichaam waar punt op snapt

            if not waterlichaam_gdf.empty: # er moet wél een waterlichaam gevonden worden
                waterlichaam = waterlichaam_gdf.iloc[0] # dan pakken we het eerste waterlichaam (als het goed is is de lengte altijd 1)
                df = lsm_lhm_snapped_gdf[lsm_lhm_snapped_gdf.within(waterlichaam.geometry)] # we zoeken naar lsm_lhm laterale knopen binnen het waterlichaam

                if not df.empty: # we hebben gevonden!
                    lsw_dm_links = [(lsw_id, i) for i in df.DM.unique()] # hier maken we links van de lsw_id naar de unieke DM-knopen
                    lsw_dm_links = [i for i in lsw_dm_links if i[1] in dm_nodes_stringified]

        return lsw_dm_links

    # set lsw_gdf index to LSWFINAL
    if lsw_gdf.index.name !="LSWFINAL":
        lsw_gdf.set_index("LSWFINAL", inplace=True)

    # snap lsm_lhm to water-bodies
    lsm_lhm_snapped_gdf = snap_to_waterbodies(lsm_lhm_gdf, lkm_waterlichamen_gdf, offset=250)

    all_links = []

    # iterate trough lsw_nodes and find
    for idx, row in enumerate(lsw_nodes_gdf.itertuples()):
        report_progress(idx, len(lsw_nodes_gdf))
        lsw_id = row.LSWFINAL
        district = row.DWRN
        dm_nodes = get_dm_nodes(dw_keys_df, district)
        dm_nodes_stringified = [str(i) for i in dm_nodes]
        lkm_links_iter = lkm_links_gdf[lkm_links_gdf.nodefrom == str(lsw_id)].itertuples()

        for row in lkm_links_iter:
            links = []
            links = find_links(row, lsw_id)

            if (not links):
                counter = 0

                while (not links) and (counter < 10) :
                    df = lkm_links_gdf[lkm_links_gdf.nodefrom == row.nodeto]

                    if not df.empty:
                        row = df.iloc[0]
                        links = find_links(row, lsw_id)
                    counter += 1

            all_links += [i for i in links if i not in all_links]

    return all_links

def find_shortest_dm_links(
        lsw_nodes_gdf: gpd.GeoDataFrame,
        dw_keys_df: pd.DataFrame,
        dm_nodes_gdf: gpd.GeoDataFrame
        ):

    all_links = []
    for row in lsw_nodes_gdf.itertuples():
        lsw_id = row.LSWFINAL
        district = row.DWRN
        dm_nodes = get_dm_nodes(dw_keys_df, district)
        dm_nodes = [str(i) for i in dm_nodes]

        dm_node = dm_nodes_gdf.at[dm_nodes_gdf.loc[dm_nodes_gdf.ID.isin(dm_nodes)].distance(row.geometry).sort_values().index[0], "ID"]

        all_links += [(lsw_id, int(dm_node))]

    return all_links

def links_to_geodataframe(
        lsw_dm_links: list,
        lsw_nodes_gdf: gpd.GeoDataFrame,
        dm_nodes_gdf: gpd.GeoDataFrame
        ):
    """Convert lsw_dm_links list to a GeoDataFrame with LineStrings."""
    warnings.simplefilter(action='ignore', category=FutureWarning)

    lsw_dm_links_gdf = gpd.GeoDataFrame(lsw_dm_links, columns = ["node_from", "node_to"], geometry = gpd.GeoSeries(), crs=28992)

    def make_line_string(row):
        report_progress(row._name, len(lsw_dm_links_gdf))
        point_from = lsw_nodes_gdf.at[row.node_from, "geometry"]
        point_to = dm_nodes_gdf.loc[dm_nodes_gdf.ID == str(row.node_to)].geometry

        return LineString([[point_from.x, point_from.y], [point_to.x, point_to.y]])

    lsw_dm_links_gdf.loc[:, "geometry"] = lsw_dm_links_gdf.apply((lambda x: make_line_string(x)), axis=1)

    lsw_dm_links_gdf["node_from"] = lsw_dm_links_gdf["node_from"].astype(str)
    lsw_dm_links_gdf["node_to"] = lsw_dm_links_gdf["node_to"].astype(str)

    return lsw_dm_links_gdf


from qiskit import QiskitError
from qiskit.compiler import assemble
from qiskit.providers.aer import QasmSimulator
from .tools import mixed_unitary_noise_model, \
                   reset_noise_model, kraus_noise_model, no_noise, \
                   simple_cnot_circuit, simple_u3_circuit

# Write the benchmarking functions here.
# See "Writing benchmarks" in the asv docs for more information.

class SimpleU3TimeSuite:
    """
    Benchmark simple circuits with just one U3 gate

    The methods defined in this class will be executed by ASV framework as many
    times as the combination of all parameters exist in `self.params`, for
    exmaple: self.params = ([1,2,3],[4,5,6]), will run all methdos 9 times:
        time_method(1,4)
        time_method(1,5)
        time_method(1,6)
        time_method(2,4)
        time_method(2,5)
        time_method(2,6)
        time_method(3,4)
        time_method(3,5)
        time_method(3,6)

    For each noise model, we want to test various configurations of number of
    qubits
    """

    def __init__(self):
        self.timeout = 60 * 20
        self.backend = QasmSimulator()
        self.circuits = []
        for i in 5, 10, 15:
            circuit = simple_u3_circuit(i)
            self.circuits.append(assemble(circuit, self.backend, shots=1))

        self.param_names = [
            "Simple u3 circuits", "Noise Model"
        ]
        self.params = (self.circuits, [
            no_noise(),
            mixed_unitary_noise_model(),
            reset_noise_model(),
            kraus_noise_model()
        ])

    def time_simple_u3(self, qobj, noise_model_wrapper):
        """ Benchmark for circuits with a simple u3 gate """
        result = self.backend.run(
            qobj, noise_model=noise_model_wrapper()
        ).result()
        if result.status != 'COMPLETED':
            raise QiskitError("Simulation failed. Status: " + result.status)

class SimpleCxTimeSuite:
    """
    Benchmark simple circuits with just on CX gate

    For each noise model, we want to test various configurations of number of
    qubits
    """

    def __init__(self):
        self.timeout = 60 * 20
        self.backend = QasmSimulator()
        self.circuits = []
        self.param_names = [
            "Simple cnot circuits", "Noise Model"
        ]
        for i in 5, 10, 15:
            circuit = simple_cnot_circuit(i)
            self.circuits.append(assemble(circuit, self.backend, shots=1))
        self.params = (self.circuits, [
            no_noise(),
            mixed_unitary_noise_model(),
            reset_noise_model(),
            kraus_noise_model()
        ])

    def time_simple_cx(self, qobj, noise_model_wrapper):
        """ Benchmark for circuits with a simple cx gate """
        result = self.backend.run(
            qobj, noise_model=noise_model_wrapper()
        ).result()
        if result.status != 'COMPLETED':
            raise QiskitError("Simulation failed. Status: " + result.status)


import configparser
import os

class Config:
    def __init__(self):
        cur_path = os.path.dirname(os.path.realpath(__file__))
        self.conf_path = os.path.join(cur_path, "spider.ini")
        self.conf = configparser.ConfigParser()
        self.conf.read(self.conf_path, encoding='utf-8')

    def get_conf_data(self):
        """
        返回配置文件的配置信息
        :return: dict
        """
        dic = {}
        dic['product'] = self.conf.get('bug', 'product')
        dic['iver'] = self.conf.get('bug', 'iver')
        return dic

    def change_conf_data(self, conf_dict):
        """
        更新配置文件信息
        :param conf_dict: 字典类型
        :return:
        """
        try:
            self.conf.set('bug', 'product', conf_dict['product'])
            self.conf.set('bug', 'iver', conf_dict['iver'])
        except Exception as e:
            print(e, "\n配置文件传入参数有误，请传入字典类型，且包含'product'和'iver'这两个key")
        self.conf.write(open(self.conf_path, 'w', encoding='utf-8'))

if __name__ == "__main__":
    conf = Config()
    conf_data = conf.get_conf_data()
    print(conf_data)
    conf_dic = {}
    conf_dic['product'] = 'nimo_ios'
    conf_dic['iver'] = '1.9.0'
    conf.change_conf_data(conf_dict=conf_dic)
    new_conf_data = conf.get_conf_data()
    print(new_conf_data)

    conf.change_conf_data(conf_dict={'product': 'nimo_android', 'iver': '1.8.0'})
    print(conf.get_conf_data())


import PipelineSearch as pipe
import sys
import os

# Used for easy restart for debugging
if 'restart' in sys.argv:
    pipe.util.restart(os.getcwd())
    print('Project directory cleaned and reset')
    exit(0)

f_primer=["XXXXXXXXXXXXXXXXXXXXXX"] # Specify your forward primer here
r_primer=["XXXXXXXXXXXXXXXXXXXXXXXXX"] # Specify your reverse primer here, if any

# Example
pipe.pipeline_functions.preprocessing_pipeline(f_primer=f_primer,
                                               r_primer=[None],
                                               paired_sequences=False,
                                               manifest_type=True,
                                               threshold=0.8,
                                               primer_error_rate=0.1,
                                               trim_taxonomy=True,
                                               no_trunc=True,
                                               tax_trunc_len=0,
                                               tax_databases=['silva', 'greengenes'])

pipe.pipeline_functions.create_function_grid(clustering_method_list=['dada2'],
                                             tax_database_list=['silva', 'greengenes'],
                                             feature_table_type_list=['pathways', 'genera', 'no_collapsing'],
                                             relative_list=['relative', 'non_relative'],
                                             prevalence_threshold_list=[0, 0.05, 0.1, 0.2],
                                             ML_target_col='Delivery_mode',
                                             ML_pos_class='C-section',
                                             ML_neg_class='Vaginal',
                                             sample_column='#SampleID',
                                             num_workers=4)

results = pipe.pipeline_functions.gather_table_paths(dir_path=os.getcwd())

pipe.pipeline_functions.combine_ML_tables(results)


# -*- coding: utf-8 -*-
"""
/***************************************************************************
 Qgis2threejs
                                 A QGIS plugin
 export terrain data, map canvas image and vector data to web browser
                             -------------------
        begin                : 2014-01-06
        copyright            : (C) 2014 Minoru Akagi
        email                : akaginch@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
"""
from PyQt4.QtCore import QVariant
from PyQt4.QtGui import QWidget, QColor, QColorDialog, QFileDialog, QMessageBox
from qgis.core import QGis
from ui.ui_widgetComboEdit import Ui_ComboEditWidget
import os

class StyleWidget(QWidget, Ui_ComboEditWidget):
  # function types
  FIELD_VALUE = 1
  COLOR = 2
  FILEPATH = 3
  HEIGHT = 4
  TRANSPARENCY = 5
  LABEL_HEIGHT = 6

  def __init__(self, funcType=None, parent=None):
    QWidget.__init__(self, parent)
    self.setupUi(self)
    self.comboBox.currentIndexChanged.connect(self.comboBoxSelectionChanged)
    self.toolButton.clicked.connect(self.toolButtonClicked)
    self.defaultValue = 0
    self.funcType = funcType
    self.func = None
    self.hasValues = False

  def setup(self, funcType=None, name=None, label=None, defaultValue=None, layer=None, fieldNames=None):
    if funcType is None:
      # use the function type passed to __init__
      funcType = self.funcType

    if self.func:
      self.func.resetDefault()

    if self.func is None or self.funcType != funcType:
      if funcType == StyleWidget.FIELD_VALUE:
        self.func = FieldValueWidgetFunc(self)
      elif funcType == StyleWidget.COLOR:
        self.func = ColorWidgetFunc(self)
      elif funcType == StyleWidget.FILEPATH:
        self.func = FilePathWidgetFunc(self)
      elif funcType == StyleWidget.HEIGHT:
        self.func = HeightWidgetFunc(self)
      elif funcType == StyleWidget.LABEL_HEIGHT:
        self.func = LabelHeightWidgetFunc(self)
      elif funcType == StyleWidget.TRANSPARENCY:
        self.func = TransparencyWidgetFunc(self)
      else:
        self.func = None
        self.setVisible(False)
        self.hasValues = False
        return
    self.func.setup(name, label, defaultValue, layer, fieldNames)
    self.setVisible(True)
    self.hasValues = True

  def comboBoxSelectionChanged(self, index):
    if self.func:
      self.func.comboBoxSelectionChanged(index)

  def toolButtonClicked(self):
    if self.func:
      self.func.toolButtonClicked()

  def hide(self):
    self.hasValues = False
    QWidget.hide(self)

  def values(self):
    if self.func and self.hasValues:
      return self.func.values()
    else:
      return []

  def setValues(self, vals):
    if self.func:
      self.func.setValues(vals)

  def addFieldNameItems(self, layer, fieldNames=None):
    fields = layer.pendingFields()
    if fieldNames is None:
      for i, field in enumerate(fields):
        if field.type() in [QVariant.Double, QVariant.Int, QVariant.LongLong, QVariant.UInt, QVariant.ULongLong]:
          self.comboBox.addItem(field.name(), WidgetFuncBase.FIRST_ATTRIBUTE + i)
    else:
      for fieldName in fieldNames:
        self.comboBox.addItem(fieldName, WidgetFuncBase.FIRST_ATTRIBUTE + fields.indexFromName(fieldName))

class WidgetFuncBase:
  FIRST_ATTRIBUTE = 100

  def __init__(self, widget):
    self.widget = widget

  def setup(self):
    # initialize widgets
    self.widget.lineEdit.setPlaceholderText("")
    self.widget.lineEdit.setVisible(True)

  def resetDefault(self):
    pass

  def comboBoxSelectionChanged(self, index):
    pass

  def toolButtonClicked(self):
    pass

  def values(self):
    return [self.widget.comboBox.itemData(self.widget.comboBox.currentIndex()), self.widget.comboBox.currentText(), self.widget.lineEdit.text()]

  def setValues(self, vals):
    index = self.widget.comboBox.findData(vals[0])
    if index != -1:
      self.widget.comboBox.setCurrentIndex(index)
    self.widget.lineEdit.setText(vals[2])

class FieldValueWidgetFunc(WidgetFuncBase):
  ABSOLUTE = 1

  def setup(self, name, label, defaultValue, layer, fieldNames):
    WidgetFuncBase.setup(self)
    self.widget.label_1.setText(name)
    self.widget.label_2.setText(label)
    self.widget.toolButton.setVisible(False)
    self.defaultValue = defaultValue

    self.widget.comboBox.clear()
    self.widget.comboBox.addItem("Fixed value", FieldValueWidgetFunc.ABSOLUTE)
    if layer:
      self.widget.addFieldNameItems(layer, fieldNames)

  def comboBoxSelectionChanged(self, index):
    itemData = self.widget.comboBox.itemData(index)
    if itemData == FieldValueWidgetFunc.ABSOLUTE:
      label = "Value"
      defaultValue = self.defaultValue
    else:
      label = "Multiplier"
      defaultValue = 1
    self.widget.label_2.setText(label)
    self.widget.lineEdit.setText(str(defaultValue))

class ColorWidgetFunc(WidgetFuncBase):
  FEATURE = 1
  RANDOM = 2
  RGB = 3

  def setup(self, name, label, defaultValue, layer, fieldNames):
    self.widget.label_1.setText("Color")
    self.widget.label_2.setText("Value")
    self.widget.lineEdit.setVisible(False)
    self.widget.lineEdit.setPlaceholderText("0xrrggbb")
    self.widget.toolButton.setVisible(False)

    self.widget.comboBox.clear()
    self.widget.comboBox.addItem("Feature style", ColorWidgetFunc.FEATURE)
    self.widget.comboBox.addItem("Random", ColorWidgetFunc.RANDOM)
    self.widget.comboBox.addItem("RGB value", ColorWidgetFunc.RGB)

  def comboBoxSelectionChanged(self, index):
    itemData = self.widget.comboBox.itemData(index)
    isRGB = itemData == ColorWidgetFunc.RGB
    self.widget.label_2.setVisible(isRGB)
    self.widget.lineEdit.setVisible(isRGB)
    self.widget.toolButton.setVisible(isRGB)

  def toolButtonClicked(self):
    color = QColorDialog.getColor(QColor(self.widget.lineEdit.text().replace("0x", "#")))
    if color.isValid():
      self.widget.lineEdit.setText(color.name().replace("#", "0x"))

  def setValues(self, vals):
    index = self.widget.comboBox.findData(vals[0])
    if index != -1:
      self.widget.comboBox.setCurrentIndex(index)
      self.widget.comboBoxSelectionChanged(index)  # make sure to update visibility
    self.widget.lineEdit.setText(vals[2])

class FilePathWidgetFunc(WidgetFuncBase):
  FILEPATH = 1

  def setup(self, name, label, defaultValue, layer, fieldNames):
    WidgetFuncBase.setup(self)
    self.widget.label_1.setText(name)
    self.widget.label_2.setText(label)
    self.widget.lineEdit.setText(str(defaultValue))
    self.widget.toolButton.setVisible(True)

    self.widget.comboBox.clear()
    self.widget.comboBox.addItem("File path", FilePathWidgetFunc.FILEPATH)

  def comboBoxSelectionChanged(self, index):
    pass

  def toolButtonClicked(self):
    directory = os.path.split(self.widget.lineEdit.text())[0]
    filename = QFileDialog.getOpenFileName(None, "Select a file", directory)
    if filename != "":
      self.widget.lineEdit.setText(filename)

class HeightWidgetFunc(WidgetFuncBase):
  ABSOLUTE = 1
  RELATIVE = 2
  RELATIVE_TO_Z = 3

  def setup(self, name, label, defaultValue, layer, fieldNames):
    WidgetFuncBase.setup(self)
    self.widget.label_1.setText("Coordinate")
    self.widget.toolButton.setVisible(False)
    self.defaultValue = 0 if defaultValue is None else defaultValue

    self.widget.comboBox.clear()
    if layer.wkbType() in [QGis.WKBPoint25D, QGis.WKBLineString25D, QGis.WKBMultiPoint25D, QGis.WKBMultiLineString25D]:
      self.widget.comboBox.addItem("Z value", HeightWidgetFunc.RELATIVE_TO_Z)
    self.widget.comboBox.addItem("Height from surface", HeightWidgetFunc.RELATIVE)
    self.widget.comboBox.addItem("Fixed value", HeightWidgetFunc.ABSOLUTE)
    if layer:
      self.widget.addFieldNameItems(layer, fieldNames)

  def comboBoxSelectionChanged(self, index):
    itemData = self.widget.comboBox.itemData(index)
    if itemData in [HeightWidgetFunc.ABSOLUTE, HeightWidgetFunc.RELATIVE]:
      label = "Value"
      defaultValue = self.defaultValue
    else:
      label = "Addend"
      defaultValue = 0
    self.widget.label_2.setText(label)
    self.widget.lineEdit.setText(str(defaultValue))

class LabelHeightWidgetFunc(WidgetFuncBase):
  ABSOLUTE = 1
  RELATIVE = 2
  RELATIVE_TO_TOP = 3

  def setup(self, name, label, defaultValue, layer, fieldNames):
    WidgetFuncBase.setup(self)
    self.widget.label_1.setText("Label height")
    self.widget.toolButton.setVisible(False)
    self.defaultValue = 0 if defaultValue is None else defaultValue

    self.widget.comboBox.clear()
    if layer.geometryType() == QGis.Point:
      self.widget.comboBox.addItem("Height from point", LabelHeightWidgetFunc.RELATIVE)
    elif layer.geometryType() == QGis.Polygon:
      self.widget.comboBox.addItem("Height from top", LabelHeightWidgetFunc.RELATIVE_TO_TOP)
      self.widget.comboBox.addItem("Height from bottom", LabelHeightWidgetFunc.RELATIVE)
    else:
      return
    self.widget.comboBox.addItem("Fixed value", HeightWidgetFunc.ABSOLUTE)
    if layer:
      self.widget.addFieldNameItems(layer, fieldNames)

  def comboBoxSelectionChanged(self, index):
    if self.widget.comboBox.itemData(index) < HeightWidgetFunc.FIRST_ATTRIBUTE:
      label = "Value"
      defaultValue = self.defaultValue
    else:
      label = "Addend"
      defaultValue = 0
    self.widget.label_2.setText(label)
    self.widget.lineEdit.setText(str(defaultValue))

class TransparencyWidgetFunc(WidgetFuncBase):
  FEATURE = 1
  LAYER = 2
  VALUE = 3

  def setup(self, name, label, defaultValue, layer, fieldNames):
    self.widget.label_1.setText("Transparency")
    self.widget.label_2.setText("Value (%)")
    self.widget.lineEdit.setVisible(False)
    self.widget.lineEdit.setPlaceholderText("0 - 100")
    self.widget.toolButton.setVisible(False)

    self.widget.comboBox.clear()
    self.widget.comboBox.addItem("Feature style", TransparencyWidgetFunc.FEATURE)
    self.widget.comboBox.addItem("Layer style", TransparencyWidgetFunc.LAYER)
    self.widget.comboBox.addItem("Fixed value", TransparencyWidgetFunc.VALUE)

  def comboBoxSelectionChanged(self, index):
    itemData = self.widget.comboBox.itemData(index)
    isValue = itemData == TransparencyWidgetFunc.VALUE
    self.widget.label_2.setVisible(isValue)
    self.widget.lineEdit.setVisible(isValue)

  def setValues(self, vals):
    index = self.widget.comboBox.findData(vals[0])
    if index != -1:
      self.widget.comboBox.setCurrentIndex(index)
      self.widget.comboBoxSelectionChanged(index)  # make sure to update visibility
    self.widget.lineEdit.setText(vals[2])


import argparse
import BLPalette
import GPLPalette
import PaletteCore

extraExt = '.extra'

argparser = argparse.ArgumentParser(
  description="Convert between Blockland and GIMP palette formats",
  epilog="Only provide one mode.")
argparser.add_argument('--to-gpl', metavar='FILENAME', help="convert Blockland .txt to .gpl")
argparser.add_argument('--to-bl-txt', metavar='FILENAME', help="convert .gpl to Blockland .txt")
argparser.add_argument('--no-restore-alphas', action='store_true',
                       help="Don't read alpha values from extra data.")
argparser.add_argument('--no-restore-divs', action='store_true',
                       help="Don't read divs from extra data.")
argparser.add_argument('--no-restore-extra', action='store_true',
                       help="Don't read any extra data.")

args = argparser.parse_args()

if args.to_gpl != None and args.to_bl_txt != None:
  print("Both modes given at once.")
elif args.to_gpl != None:
  blpal = BLPalette.BLPalette()
  gplpal = GPLPalette.GPLPalette()

  outfilename = args.to_gpl[:args.to_gpl.rindex('.')] + '.gpl'
  extrafilename = outfilename + extraExt
  print("Reading {:s}...".format(args.to_gpl))
  with open(args.to_gpl, "r") as infile:
    for line in infile:
      blpal.add_line(line)

  print("Converting data structures...")
  for color in blpal.palette:
    gplpal.add_entry(GPLPalette.GPLColor.fromColor(color))

  print("Writing extra data to {:s}...".format(extrafilename))
  with open(extrafilename, 'w') as extrafile:
    extrafile.write(str(len(blpal.palette)) + ' ')
    for color in enumerate(blpal.palette):
      extrafile.write(str(color[1].a) + ' ')
    extrafile.write(str(len(blpal.divs)) + ' ')
    for div in blpal.divs:
      extrafile.write(str(div[0]) + ' ')
    for div in blpal.divs:
      extrafile.write(str(div[1]) + ' ')

  print("Writing to {:s}...".format(outfilename))
  with open(outfilename, "w") as outfile:
    for line in gplpal:
      outfile.write(line + '\n')

  print("Done!")
elif args.to_bl_txt != None:
  blpal = BLPalette.BLPalette()
  gplpal = GPLPalette.GPLPalette()

  outfilename = args.to_bl_txt[:args.to_bl_txt.rindex('.')] + '.txt'
  extrafilename = args.to_bl_txt + extraExt
  print("Reading {:s}...".format(args.to_bl_txt))
  with open(args.to_bl_txt, "r") as infile:
    for line in infile:
      gplpal.add_line(line)

  print("Converting data structures...")
  for color in gplpal.palette:
    blpal.add_entry(BLPalette.BLColor.fromColor(color))

  if not args.no_restore_extra:
    print("Reading extra data from {:s}...".format(extrafilename))
    extra = ""
    with open(extrafilename, 'r') as extrafile:
      extra = extrafile.read()
    extra = extra.split()
    alphacount = int(extra[0])
    alphastart = 1
    alphaend = 1 + alphacount
    divcount = int(extra[alphaend])
    divlinesstart = 1 + alphacount + 1
    divlinesend = 1 + alphacount + 1 + divcount
    divnamesstart = 1 + alphacount + 1 + divcount
    divnamesend = 1 + alphacount + 1 + divcount + divcount
    alphas = extra[alphastart:alphaend]
    divlines = extra[divlinesstart:divlinesend]
    divnames = extra[divnamesstart:divnamesend]
    if not args.no_restore_alphas:
      for alpha in enumerate(alphas):
        blpal.palette[alpha[0]].a = int(alpha[1])
    if not args.no_restore_divs:
      for i in range(0, divcount):
        blpal.add_div(int(divlines[i]), divnames[i])

  print("Writing to {:s}...".format(outfilename))
  with open(outfilename, "w") as outfile:
    for line in blpal:
      outfile.write(line + '\n')

  print("Done!")
else:
  print("No mode given.")
  argparser.print_usage()


import sys

input = sys.stdin.readline

K, N = map(int, input().split())
lan = [int(input()) for _ in range(K)]
end = max(lan)

def length_def(n):
    count = 0
    for item in lan:
        count += item // n
    return count

def bsearch(start, end, N):
    if start > end:
        return end

    mid = (start + end) // 2
    length = length_def(mid)
    if length >= N:
        return bsearch(mid + 1, end, N)
    else:
        return bsearch(start, mid - 1, N)

print(bsearch(1, end, N))


import openpyxl

def convert_result_to_excel(result,excel_file_path):
  wb=openpyxl.Workbook()
  sheet=wb['Sheet']

  header_list=list(result[0].keys())
  for c in range(len(header_list)):
    sheet.cell(row=1,column=c+1).value=header_list[c]

  for r in range(len(result)):
    for c in range(len(header_list)):
      sheet.cell(row=r+2,column=c+1).value=result[r][header_list[c]]

  wb.save(excel_file_path)


from django.conf.urls import url
from app.views import *

urlpatterns = [
    # Matches any html file - to be used for gentella
    # Avoid using your .html in your resources.
    # Or create a separate django app.
    # url(r'^.*\.html', views.gentella_html, name='gentella'),

#新增评论
    url(r'^add/$', ReviewCreate.as_view(), name="review-add"),

    url(r'^.*\.html',HaOpsView.as_view(),),

    # The home page
    url(r'^$', IndexView.as_view()),

]


from queue import Queue

def btf(graph: list[list[str]], i: int, j: int, new_color: str, m: int, n: int) -> None:
    old_color = graph[i][j]
    if old_color == new_color:
        return

    queue = Queue()
    queue.put((i, j))

    while not queue.empty():
        i, j = queue.get()
        if i < 0 or i >= n or j < 0 or j >= m or graph[i][j] != old_color:
            continue
        else:
            graph[i][j] = new_color
            queue.put((i + 1, j))
            queue.put((i - 1, j))
            queue.put((i, j + 1))
            queue.put((i, j - 1))


# drunktweet.py
'''
Print out possible drunk tweets from anywhere in the world.

Usage: ./drunktweet.py London, UK
'''

import regex
import requests
import json
import simplejson, urllib
import sys

def geosearch(query):
    args = {
        'address': query,
        'sensor': 'false',
    }
    googurl = "http://maps.googleapis.com/maps/api/geocode/json?" + urllib.urlencode(args)
    result = simplejson.load(urllib.urlopen(googurl))

    #{'lat': 21.6345879, 'lng': -160.0860288}
    sw=[str(result['results'][0]['geometry']['viewport']['southwest']['lng']),str(result['results'][0]['geometry']['viewport']['southwest']['lat'])]
    ne=[str(result['results'][0]['geometry']['viewport']['northeast']['lng']),str(result['results'][0]['geometry']['viewport']['northeast']['lat'])]

    return [sw,ne]

# Terms for being "wasted"
terms = { 'drunk','wasted','buzzed','hammered','plastered' }

# A fuzzy regex for people who can't type
pat = regex.compile(r"(?:\L<terms>){i,d,s,e<=2}$", regex.I, terms=terms)

# Connect to the Twitter streaming API
url   = "https://stream.twitter.com/1/statuses/filter.json"
location=geosearch(" ".join(sys.argv[1:]))
parms = {
    'locations' : location[0][0]+","+location[0][1]+","+location[1][0]+","+location[1][1]
    }
auth  = ('diffra','password')
r = requests.post(url, data=parms, auth=auth)

# Print possible candidates
for line in r.iter_lines():
    if line:
        tweet = json.loads(line)
        status = tweet.get('text',u'')
        words = status.split()
        if any(pat.match(word) for word in words):
           print(tweet['user']['screen_name'], status)


from __future__ import annotations

from typing import Optional, Tuple

from retentioneering.backend.tracker import (
    collect_data_performance,
    time_performance,
    track,
)
from retentioneering.constants import DATETIME_UNITS
from retentioneering.utils.doc_substitution import docstrings

from ..types import EventstreamType

class LabelCroppedPathsHelperMixin:
    @docstrings.with_indent(12)
    @time_performance(
        scope="label_cropped_paths",
        event_name="helper",
        event_value="combine",
    )
    def label_cropped_paths(
        self: EventstreamType,
        left_cutoff: Optional[Tuple[float, DATETIME_UNITS]],
        right_cutoff: Optional[Tuple[float, DATETIME_UNITS]],
    ) -> EventstreamType:
        """
        A method of ``Eventstream`` class that creates new synthetic event(s) for each user based
        on the timeout threshold: ``cropped_left`` and ``cropped_right``.

        Parameters
        ----------
            %(LabelCroppedPaths.parameters)s

        Returns
        -------
        Eventstream
            Input ``eventstream`` with new synthetic events.

        """
        calling_params = {
            "left_cutoff": left_cutoff,
            "right_cutoff": right_cutoff,
        }
        not_hash_values = ["left_cutoff", "right_cutoff"]

        # avoid circular import
        from retentioneering.data_processors_lib import (
            LabelCroppedPaths,
            LabelCroppedPathsParams,
        )
        from retentioneering.preprocessing_graph import PreprocessingGraph
        from retentioneering.preprocessing_graph.nodes import EventsNode

        p = PreprocessingGraph(source_stream=self)  # type: ignore

        params = dict(left_cutoff=left_cutoff, right_cutoff=right_cutoff)

        node = EventsNode(processor=LabelCroppedPaths(params=LabelCroppedPathsParams(**params)))  # type: ignore
        p.add_node(node=node, parents=[p.root])
        result = p.combine(node)
        del p
        collect_data_performance(
            scope="label_cropped_paths",
            event_name="metadata",
            called_params=calling_params,
            not_hash_values=not_hash_values,
            performance_data={},
            eventstream_index=self._eventstream_index,
            parent_eventstream_index=self._eventstream_index,
            child_eventstream_index=result._eventstream_index,
        )

        return result


from pydoc import doc
from sqlalchemy import true
from stringcolor import *
def fac(n):

    counter=1
    if n == 0:
        return 0
    else:

        for i in range(0,n):
            for j in range(n,0,-1):
                if i*j==n:
                    print(i,j)
                    counter+=1
                else:
                    continue
    print("Total combination are :===>",counter)
if __name__=="__main__":
    fac(int(input("Enter Number")))


import datetime
import os
import re

import pyspark.sql as psql

from seldonite import collect, sources, run

def clean_date(txt):
    try:
        if txt.startswith('java.util.GregorianCalendar'):
            year_match = re.search('(?<=,YEAR=)\d+', txt)
            month_match = re.search('(?<=,MONTH=)\d+', txt)
            day_match = re.search('(?<=,DAY_OF_MONTH=)\d+', txt)

            if (year_match and month_match and day_match):
                year = int(year_match.group(0))
                month = int(month_match.group(0)) + 1
                day = int(day_match.group(0))
                return datetime.date(year, month, day)
            else:
                raise Exception("Unrecognised date format")
        elif txt.startswith('{"$date":'):
            match = re.search('[0-9]+', txt)
            if match:
                return datetime.date.fromtimestamp(int(match.group(0)[:-3]))
            else:
                raise Exception("Unrecognised date format")
        else:
            raise Exception("Unrecognised date format")
    except Exception as e:
        raise Exception(f"Received error: {str(e)}, for text: {txt}")

def main():
    master_url = 'k8s://https://10.140.16.25:6443'
    db_connection_string = os.environ['MONGO_CONNECTION_STRING']

    spark_conf = {
        'spark.kubernetes.authenticate.driver.serviceAccountName': 'ben-dev',
        'spark.kubernetes.driver.pod.name': 'seldonite-driver',
        'spark.driver.host': 'seldonite-driver',
        'spark.driver.port': '7078'
    }

    db_name = 'political_events'
    db_table_in = 'reuters_news'
    db_table_out = 'reuters_news_2'

    mongo_source = sources.news.MongoDB(db_connection_string, db_name, db_table_in, partition_size_mb=64)

    collector = collect.Collector(mongo_source)

    clean_date_udf = psql.functions.udf(clean_date, returnType=psql.types.DateType())
    collector.apply_udf(clean_date_udf, 'publish_date')

    runner = run.Runner(collector, master_url=master_url, num_executors=11, executor_cores=4, executor_memory='48g', driver_memory='64g', spark_conf=spark_conf)
    runner.send_to_database(db_connection_string, db_name, db_table_out)

if __name__ == '__main__':
    main()


from django import forms

from .models import RSVP

class RSVPForm(forms.ModelForm):
    class Meta:
        model = RSVP
        fields = ['name', 'email', 'attending', 'guests', 'address1', 'address2', 'city', 'zip_code',
                  'state', 'song_request']
        widgets = {
            'attending': forms.RadioSelect(
                choices=[(True, 'Yes'), (False, 'No')],
                attrs={'class': 'form-check-input'},
            )
        }


import logging
import asyncio
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher.filters.state import State, StatesGroup
# работа с базой данных
from sqlalchemy import create_engine
from sqlalchemy.orm import Session, sessionmaker

import base.logics
from base.models import User, Purchase

# Работа с файловой системой и пр.
from os import getenv
from sys import exit
# Для превращения словарей в объекты (хз чет не догоняю)
from munch import DefaultMunch
import datetime

# Пользовательские материалы в проекте
# from content.descriptions import instructions, help, greetings, admins_start
import config

# Todo - выбрать способ наполнения базы текстами

# Todo Добавить продажу: кнопка, ссылка на акк. и  его проверка, оплата, уведомление об оплате со ссылкой.
# Todo Учёт заданий. Создано, оплачено, выполнено.

# Todo Заказать анализы: кнопка - сслыка - проверка - оплата -?контроль оплаты
#  - сообщение об оплате - сообщение о заказе админу.

# состояние пользователя в чате - возможно удалить
class dialog(StatesGroup):
    spam = State()
    blacklist = State()
    whitelist = State()

# Включение бота и диспетчера
bot_token = getenv("BOT_TOKEN")
if not bot_token:
    exit("Error: no token provided")
storage = MemoryStorage()
bot = Bot(token=bot_token)
dp = Dispatcher(bot=bot, storage=storage)
logging.basicConfig(level=logging.INFO)

# запускаем движок базы данных
engine = create_engine(config.database)

# Пример админ меню на развитие функционала
kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
kb.add(types.InlineKeyboardButton(text="Рассылка"))
kb.add(types.InlineKeyboardButton(text="Добавить в ЧС"))
kb.add(types.InlineKeyboardButton(text="Убрать из ЧС"))
kb.add(types.InlineKeyboardButton(text="Статистика"))

# Хороший генератор кнопок. Если потребуются разные форматы на 3 и более столбца, то применять. Пока как пример.
def build_menu(buttons, n_cols,
               header_buttons=None,
               footer_buttons=None):
    menu = [buttons[i:i + n_cols] for i in range(0, len(buttons), n_cols)]
    if header_buttons:
        menu.insert(0, [header_buttons])
    if footer_buttons:
        menu.append([footer_buttons])
    return menu

def initiation():

    if base.logics.get_users():
        print(f'С базой всё ОК, запускаем сервис')
    else:
        None
    # Todo Если с базой не ОК - не работать дальше.

async def first_time_user(message):
    session = Session(bind=engine)
    d = session.query(User.id).filter(User.id == message.from_user.id).scalar()
    f = message.from_user
    if d is None:
        print(f'Такого пользователя нет')
        user = User(id=f.id,
                    is_bot=f.is_bot,
                    first_name=f.first_name,
                    username=f.username,
                    last_name=f.last_name,
                    language_code=f.language_code,
                    can_join_groups=f.can_join_groups,
                    can_read_all_group_messages=f.can_read_all_group_messages,
                    supports_inline_queries=f.supports_inline_queries,
                    role='user',
                    updated=datetime.datetime.now()
                    )
        try:
            session.add(user)
            session.commit()
        except Exception as e:
            print(f'При добавлении базы возникла ошибка {e}')
        else:
            print(f'Добавили пользователя {f.first_name}')
            return True
    else:
        print(f'Стартанул пользователь {message.from_user.first_name}')
        return False

async def admin_user(message):
    session = Session(bind=engine)
    d = session.query(User.role).filter(User.id == message.from_user.id).scalar()
    print(d)
    if d == 'admin':
        print(f'Зашёл Админ')
        return True
    else:
        return False

async def start(message: types.Message):
    session = Session(bind=engine)
    if await first_time_user(message):
        await message.answer(greetings)
        await message.answer(help)
    elif await admin_user(message):
        # Создание клавиатуры со switch-кнопками и отправка сообщения для админа
        switch_keyboard = types.InlineKeyboardMarkup()
        switch_keyboard.add(types.InlineKeyboardButton(
            text="Отправить бота",
            switch_inline_query=""))
        switch_keyboard.add(types.InlineKeyboardButton(
            text="Вызвать бота здесь",
            switch_inline_query_current_chat=""))
        await message.answer(admins_start, reply_markup=switch_keyboard)
    else:
        await message.answer(help)

# Todo проработать передачу данных и состояний через
data = []
i_key = str()
i_value = str()

async def instruction_key(message: types.Message):
    global i_key
    keyboard = types.InlineKeyboardMarkup(row_width=2, inline_keyboard=None)
    buttons = []
    for note_type in instructions.keys():
        buttons.append(types.InlineKeyboardButton(text=note_type, callback_data=note_type))
    keyboard.add(*buttons)

    await message.answer("Выбери <u>вид записи</u>.", reply_markup=keyboard, parse_mode=types.ParseMode.HTML)

@dp.callback_query_handler(lambda call: call.data == 'back_to_instruction')
async def back_to_instruction(call: types.CallbackQuery):
    await call.answer()
    await bot.edit_message_reply_markup(call.message.chat.id,
                                        message_id=call.message.message_id)  # удаляем кнопки у последнего сообщения
    await bot.delete_message(chat_id=call.message.chat.id, message_id=call.message.message_id)

    await instruction_key(call.message)

@dp.callback_query_handler(lambda call: call.data in instructions.keys())
async def instruction_value(call: types.CallbackQuery):

    await call.answer()
    print(f'Запрос от пользователя "{call.from_user.first_name}" - "{call.data}"')
    global data, i_key
    i_key = call.data
    await bot.edit_message_reply_markup(call.message.chat.id,
                                        message_id=call.message.message_id)  # удаляем кнопки у последнего сообщения
    keyboard = types.InlineKeyboardMarkup(row_width=2)
    # Собираем меню кнопок
    buttons = []
    for element in instructions[i_key]:
        buttons.append(types.InlineKeyboardButton(text=element, callback_data=element))
    keyboard.add(*buttons)
    # отдельно добавляем кнопку Назад, чтобы она всегда была внизу и одна
    keyboard.add(types.InlineKeyboardButton(text="Назад", callback_data="back_to_instruction"))
    data = instructions[i_key].keys()
    await call.message.edit_text(f'и элемент из "{call.data}" ? ', reply_markup=keyboard)

@dp.callback_query_handler(lambda call: call.data in data)
async def instruction_notice(call: types.CallbackQuery):
    global i_value
    i_value = call.data
    # print(data)
    # print(i_key)
    # print(i_value)
    # print(call)
    print(f'Запрос деталей от пользователя "{call.from_user.first_name}" - "{call.data}"')
    await bot.answer_callback_query(callback_query_id=call.id,
                                    show_alert=True,
                                    text=f'В {call.data} важно:\n {instructions[i_key][i_value]}')
    await call.answer()

# Система хранения состояний. Пока не разобрался.
async def shutdown(dispatcher: Dispatcher):
    await dispatcher.storage.close()
    await dispatcher.storage.wait_closed()

async def main():
    initiation()
    try:
        dp.register_message_handler(start, commands={"start"})
        dp.register_message_handler(instruction_key, commands={"ads_formats"})
        await dp.start_polling()
    finally:
        await bot.close()

asyncio.run(main())


import os

import netCDF4
import pytest
import matplotlib.pyplot as plt

import config
from weatherpy import maps
from weatherpy.radar.nexradl2 import Nexrad2Plotter

RADAR_FILE = 'Level2_KGLD_20170713_0200.nc'

radar_dataset = None

@pytest.fixture(scope='module', autouse=True)
def lazyloaddataset():
    print('loading...')
    global radar_dataset
    radar_dataset = netCDF4.Dataset(os.sep.join([config.TEST_DATA_DIR, RADAR_FILE]))
    yield
    print('closing...')
    radar_dataset.close()

@pytest.mark.mpl_image_compare(tolerance=20)
def test_plot_reflectivity():
    fig = plt.figure()
    _run_basic_test_with('Reflectivity')
    return fig

@pytest.mark.mpl_image_compare(tolerance=20)
def test_plot_velocity():
    fig = plt.figure()
    _run_basic_test_with('RadialVelocity')
    return fig

@pytest.mark.mpl_image_compare(tolerance=20)
def test_plot_differential_reflectivity():
    fig = plt.figure()
    _run_basic_test_with('DifferentialReflectivity')
    return fig

@pytest.mark.mpl_image_compare(tolerance=20)
def test_plot_correlation_coefficient():
    fig = plt.figure()
    _run_basic_test_with('CorrelationCoefficient')
    return fig

@pytest.mark.mpl_image_compare(tolerance=20)
def test_plot_reflectivity_with_limiting_range_ring():
    fig = plt.figure()
    plotter = Nexrad2Plotter(radar_dataset)
    orig_map = plotter.default_map()
    map_to_use = maps.LargeScaleMap(orig_map.crs)
    map_to_use.extent = orig_map.extent

    mapper, _ = plotter.make_plot(mapper=map_to_use)
    mapper.draw_default()
    plotter.range_ring(mapper)
    return fig

@pytest.mark.mpl_image_compare(tolerance=20)
def test_plot_reflectivity_with_nonlimiting_range_ring():
    fig = plt.figure()
    plotter = Nexrad2Plotter(radar_dataset)
    orig_map = plotter.default_map()
    map_to_use = maps.LargeScaleMap(orig_map.crs)
    map_to_use.extent = orig_map.extent

    mapper, _ = plotter.make_plot(mapper=map_to_use)
    mapper.draw_default()
    plotter.range_ring(mapper, limit=False, fit_to_ring=False)
    return fig

def _run_basic_test_with(radartype=None, hires=True, sweep=0):
    plotter = Nexrad2Plotter(radar_dataset)
    orig_map = plotter.default_map()
    map_to_use = maps.LargeScaleMap(orig_map.crs)
    map_to_use.extent = orig_map.extent

    plotter.set_radar(radartype, hires, sweep)
    mapper, _ = plotter.make_plot(mapper=map_to_use)
    mapper.draw_default()


import cv2
import json
import numpy as np

class Parameters:
    """
    Parameters used for transferring between camera view and Bird Eye view,
    and between Bird Eye view and lat / lon
    List of Parameters:

        unwarp_M:       The matrix used for unwarping (from Camera view to Bird Eye View)
        unwarp_Minv:    Inverted unwarp_M (from Bird Eye to Camera View)
        lonA, lonB:     longitude = lonA * x + lonB, where x - pixel coordinate
        latA, latB:     latitude = latA * y + latB, where y - pixel coordinate

    This class contains also methods that allow to load data from json file and generate the necessary
    parameters

    """

    def __init__(self):
        self.unwarp_M = None # The matrix used for unwarping (from Camera view to Bird Eye View)
        self.unwarp_Minv = None # Inverted unwarp_M (from Bird Eye to Camera View)
        self.lonA, self.lonB = None, None # longitude = lonA * x + lonB, where x - pixel coordinate
        self.latA, self.latB = None, None # latitude = latA * y + latB, where y - pixel coordinate

        self.elevation = None # Elevation of an intersection

        self.lanes_mask = None

    def __generate_unwarp_matrices(self, cameraPoints, birdEyePoints):
        """
        Generates the matrices responsible for switching between Camera and Bird Eye views.
        Arguments:
            cameraPoints  - list of lists of pixel coordinates from the Camera Image
                            [ [x1, y1], [x2, y2], [x3, y3], [x4, y4] ]
            birdEyePoints - list of lists of pixel coordinates from the Bird Eye Image
                            [ [x1, y1], [x2, y2], [x3, y3], [x4, y4] ]
        """

        # Check data

        assert isinstance(cameraPoints, (list, tuple)), (
            'cameraPoints should be a list or a tuple. It is a {}'.format(type(cameraPoints))
        )
        assert isinstance(birdEyePoints, (list, tuple)), (
            'birdEyePoints should be a list or a tuple. It is a {}'.format(type(birdEyePoints))
        )
        assert len(cameraPoints) == 4, (
            'Len of cameraPoints should be 4. It is {}'.format(len(cameraPoints))
        )
        assert len(birdEyePoints) == 4, (
            'Len of birdEyePoints should be 4. It is {}'.format(len(birdEyePoints))
        )
        for i in range(4):
            assert isinstance(cameraPoints[i], (list, tuple)), (
                'cameraPoints[{}] should be a list or a tuple. It is a {}'
                    .format(i, type(cameraPoints[i]))
            )
            assert isinstance(birdEyePoints[i], (list, tuple)), (
                'birdEyePoints[{}] should be a list or a tuple. It is a {}'
                    .format(i, type(birdEyePoints[i]))
            )
            assert len(cameraPoints[i]) == 2, (
                'Len of cameraPoints[{}] should be 2. It is {}'.format(i, len(cameraPoints))
            )
            assert len(birdEyePoints[i]) == 2, (
                'Len of birdEyePoints[{}] should be 2. It is {}'.format(i, len(birdEyePoints))
            )

        cameraPoints = np.float32(cameraPoints)
        birdEyePoints = np.float32(birdEyePoints)

        self.unwarp_M = cv2.getPerspectiveTransform(cameraPoints, birdEyePoints)
        self.unwarp_Minv = cv2.getPerspectiveTransform(birdEyePoints, cameraPoints)

    def __generate_latlon_coefs(self, birdEyeCoordinates, latLonCoordinates):
        """
        Generates the coeffitiens responsible for going from pixels to latitudes, longitudes.
        Arguments:
            birdEyeCoordinates -    list of lists of coordinates from the Bird Eye Image
                                    [ [x1, y1], [x2, y2] ]
            latLonCoordinates -     list of lists of longitudes and latitudes corresponding with
                                    points stored in birdEyeCoordinates
                                    [ [lon1, lat1], [lon2, lat2] ]
        """

        # Check data

        assert isinstance(birdEyeCoordinates, (list, tuple)), (
            'birdEyeCoordinates should be a list or tuple. It is a {}'.format(type(birdEyeCoordinates))
        )
        assert isinstance(latLonCoordinates, (list, tuple)), (
            'latLonCoordinates should be a list or tuple. It is a {}'.format(type(latLonCoordinates))
        )
        assert len(birdEyeCoordinates) == 2, (
            'Len of birdEyeCoordinates should be 2. It is {}'.format(len(birdEyeCoordinates))
        )
        assert len(latLonCoordinates) == 2, (
            'Len of latLonCoordinates should be 2. It is {}'.format(len(latLonCoordinates))
        )
        for i in range(2):
            assert isinstance(birdEyeCoordinates[i], (list, tuple)), (
                'birdEyeCoordinates[{}] should be a list or tuple. It is a {}'
                    .format(i, type(birdEyeCoordinates[i]))
            )
            assert isinstance(latLonCoordinates[i], (list, tuple)), (
                'latLonCoordinates[{}] should be a list or tuple. It is a {}'
                    .format(i, type(latLonCoordinates[i]))
            )
            assert len(birdEyeCoordinates[i]) == 2, (
                'Len of birdEyeCoordinates[{}] should be 2. It is {}'.format(i, len(birdEyeCoordinates))
            )
            assert len(latLonCoordinates) == 2, (
                'Len of latLonCoordinates[{}] should be 2. It is {}'.format(i, len(latLonCoordinates))
            )

        x1, y1 = birdEyeCoordinates[0]
        x2, y2 = birdEyeCoordinates[1]
        lon1, lat1 = latLonCoordinates[0]
        lon2, lat2 = latLonCoordinates[1]

        self.lonA = (lon1 - lon2) / (x1 - x2)
        self.lonB = lon1 - x1 * self.lonA

        self.latA = (lat1 - lat2) / (y1 - y2)
        self.latB = lat1 - y1 * self.latA

    def generateParameters(self, jsonfile):
        """
        Computes and sets parameters based on the given json file
        Arguments:
            jsonfile - path to the file
        """

        with open(jsonfile) as f:
            data = json.load(f)
        self.__generate_unwarp_matrices(data['cameraPoints'], data['birdEyePoints'])
        self.__generate_latlon_coefs(data['birdEyeCoordinates'], data['latLonCoordinates'])

        if 'elevation' in data:
            self.elevation = data['elevation']

        if 'lanes_mask' in data:
            self.lanes_mask = data['lanes_mask']

    def birdEye2Geocoordinates(self, x, y):
        """
        Computes longitude and latitude given the image point coordinates
        Arguments:
            x, y - point coordinates (bird eye view)
        Returns:
            longitude, latitude (float, float) - geocoordinates
        """
        longitude = self.lonA * x + self.lonB
        latitude = self.latA * y + self.latB
        return longitude, latitude

    def geocoordinates2BirdEye(self, longitude, latitude):
        """
        Computes birdeye view x and y given the geocoordinates
        Arguments:
            longitude, latitude - geocoordinates
        Returns:
            x, y (int, int) - point coordinates
        """
        x = (longitude - self.lonB) / self.lonA
        y = (latitude - self.latB) / self.latA

        return np.round(x).astype(int), np.round(y).astype(int)

    def camera2BirdEye(self, x, y):
        src = np.array([[[x, y]]], dtype='float32')
        trans = cv2.perspectiveTransform(src, self.unwarp_M)
        return trans[0][0]

    def camera2Geocoordinates(self, x, y):
        birdEyeX, birdEyeY = self.camera2BirdEye(x, y)
        return self.birdEye2Geocoordinates(birdEyeX, birdEyeY)


import sys
import json
from PyQt5 import Qsci
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit
from PyQt5.QtGui import QSyntaxHighlighter, QTextCharFormat, QFont
from PyQt5.QtCore import Qt, QRegExp
from gui import Ui_PyJaMa

class JsonSyntaxHighlighter(QSyntaxHighlighter):
    def __init__(self, parent):
        super(JsonSyntaxHighlighter, self).__init__(parent)
        self.json_format = QTextCharFormat()
        self.json_format.setForeground(Qt.darkBlue)
        self.json_format.setFontWeight(QFont.Bold)

        self.string_format = QTextCharFormat()
        self.string_format.setForeground(Qt.darkGreen)

        self.number_format = QTextCharFormat()
        self.number_format.setForeground(Qt.red)

    def highlightBlock(self, text):
        state = self.previousBlockState()
        startIndex = 0

        for i, char in enumerate(text):
            if state == 0:
                if char == '"':
                    if i == 0 or text[i - 1] != '\\':
                        startIndex = i
                        state = 1
                elif char in ('{', '}', '[', ']'):
                    self.setFormat(i, 1, self.json_format)
                elif char.isDigit() or char in ('-', '.', 'e', 'E'):
                    state = 2
            elif state == 1:  # Inside a string
                if char == '"' and text[i - 1] != '\\':
                    self.setFormat(startIndex, i - startIndex + 1, self.string_format)
                    state = 0
            elif state == 2:  # Inside a number
                if not (char.isDigit() or char in ('-', '.', 'e', 'E')):
                    self.setFormat(startIndex, i - startIndex, self.number_format)
                    state = 0

        self.setCurrentBlockState(state)

class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_PyJaMa()  # Create an instance of the generated UI class

        self.ui.setupUi(self)  # Set up the UI
        Qsci.QsciLexerJSON(self.ui.field_input)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())


import random

energy = 1000
energy_per_move = 0
energy_per_move_cost = 100

coins = 0
coins_per_move = 0
coins_per_move_cost = 100

chest_drop_chance = 50
chest_drop_chance_cost = 100
better_chest_loot = 0

additional_move_chance = 0

amount_of_basic = 0
amount_of_rare = 0
amount_of_epic = 0
amount_of_legendary = 0
amount_of_MYTHIC = 0
chests_dropped_total = 0

chests_dropped_list = [['basic', amount_of_basic], ['rare', amount_of_rare], [
    'epic', amount_of_epic], ['legendary', amount_of_legendary], ['MYTHIC', amount_of_MYTHIC]]
moves_made = 0

x = 0
y = 0

chests_rarity = ['basic', 'rare', 'epic', 'legendary', 'MYTHIC']
chests_drop_chance = [0.5, 0.2, 0.15, 0.04, 0.01]

"""
    Showing player's position on the map in x, y format
    x - forward (+), backwards(-)
    y - left (-), right (+)
"""

def show_position():
    print(f"""
                Your Position on the map
                x: {x}
                y: {y}
    """)

"""
    Showing all the statistics in the game you currently have
"""

def stats():
    print(f"""
                x: {x},  y: {y}
                coins - {coins},   energy - {energy}
                total chests dropped - {chests_dropped_total}
                moves made - {moves_made}
                                                        Bonuses:
                Passive Income - +{coins_per_move},   Energy Flow - +{energy_per_move},   Luck - {chest_drop_chance}%
    """)

"""
    Allows you to buy bonuses that boost your gameplay
"""

def buy_bonus():
    print(f"""
                1 - buy Passive Income (+5) - cost: {coins_per_move_cost}
                2 - buy Energy Flow (+5) - cost: {energy_per_move_cost}
                3 - buy Luck (+5) - cost: {chest_drop_chance_cost}
                4 - exit
    """)

def list_of_bonuses():
    print(f"""
                Passive Income - Get passive income every move - {coins_per_move}
                Energy Flow - Get more energy every move - {energy_per_move}
                Luck - Higher chance for dropping chest every round - {chest_drop_chance}
    """)

def chest_drops():
    print(f"""
                Chance for any chest = {chest_drop_chance}%
                Chests can contain:
                Basic - between 90 and 110 coins (50%)
                Rare - between 180 and 220 coins (20%)
                Epic - between 450 and 550 coins (15%)
                Legendary - between 675 and 825 coins (4%)
                MYTHIC - between 900 and 1100 coins (1%)
    """)

"""
    Gives value between two price ranges
    Params: value->int percentRange->int (=10)
    Returns: int
"""

def approximate_value(value, percentRange=10):
    lowestValue = value - (percentRange / 100) * value
    highestValue = value + (percentRange / 100) * value
    return random.randint(lowestValue, highestValue)

def chests_dropped():
    print(f"""
                Total chests dropped: {chests_dropped_total}

                Basic chests dropped: {chests_dropped_list[0]}
                Rare chests dropped: {chests_dropped_list[1]}
                Epic chests dropped: {chests_dropped_list[2]}
                Legendary chests dropped: {chests_dropped_list[3]}
                MYTHIC chests dropped: {chests_dropped_list[4]}
    """)

print("""
                                        Game Info:

                This game is all about making choices and moving around the map.
                You can go in four directions - forward, left, backwards, right.
                Every move you have a chance to find a chest with coins inside.
                With coins you can buy bonuses which helps you in game.
                Bonus cost is growing every time you buy one.
                BE CAREFUL - if your energy runs down the game ends
                Have Fun!

""")

move_range = int(input(
    'Choose your move range for whole game (min is 1, max is 10) - move range depends on energy energy consumption every move: '))

while energy != 0:
    if move_range < 1 or move_range > 10:
        print("Wrong move range!")
        break
    choice = input("""
                Choose your next move:
                w - go straight
                a - go left
                s - go back
                d - go right
                1 - check your position (the position is given as x and y)
                2 - check stats
                3 - buy bonuses
                4 - my bonuses
                5 - chests info
                6 - my chests
                7 - END GAME
    """)
    if choice == 'w':
        chest_drop = random.randint(1, 2)
        chest_loot = random.choices(chests_rarity, chests_drop_chance)
        x += move_range
        coins += coins_per_move
        energy -= move_range
        energy += energy_per_move
        moves_made += 1
        if chest_drop == 1:
            if chest_loot == ['basic']:
                coins_from_chest = approximate_value(100)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_basic += 1
                chests_dropped_list[0][1] += 1
                print(
                    f'You have found basic chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['rare']:
                coins_from_chest = approximate_value(200)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_rare += 1
                chests_dropped_list[1][1] += 1
                print(
                    f'You have found rare chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['epic']:
                coins_from_chest = approximate_value(500)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_epic += 1
                chests_dropped_list[2][1] += 1
                print(
                    f'You have found epic chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['legendary']:
                coins_from_chest = approximate_value(750)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_legendary += 1
                chests_dropped_list[3][1] += 1
                print(
                    f'You have found legendary chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['MYTHIC']:
                coins_from_chest = approximate_value(1000)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_MYTHIC += 1
                chests_dropped_list[4][1] += 1
                print(
                    f'You have found MYTHIC chest with {coins_from_chest} coins inside!')
        else:
            continue

    elif choice == 'a':
        chest_drop = random.randint(1, 2)
        chest_loot = random.choices(chests_rarity, chests_drop_chance)
        y -= move_range
        coins += coins_per_move
        energy -= move_range
        energy += energy_per_move
        moves_made += 1
        if chest_drop == 1:
            if chest_loot == ['basic']:
                coins_from_chest = approximate_value(100)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_basic += 1
                chests_dropped_list[0][1] += 1
                print(
                    f'You have found basic chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['rare']:
                coins_from_chest = approximate_value(200)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_rare += 1
                chests_dropped_list[1][1] += 1
                print(
                    f'You have found rare chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['epic']:
                coins_from_chest = approximate_value(500)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_epic += 1
                chests_dropped_list[2][1] += 1
                print(
                    f'You have found epic chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['legendary']:
                coins_from_chest = approximate_value(750)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_legendary += 1
                chests_dropped_list[3][1] += 1
                print(
                    f'You have found legendary chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['MYTHIC']:
                coins_from_chest = approximate_value(1000)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_MYTHIC += 1
                chests_dropped_list[4][1] += 1
                print(
                    f'You have found MYTHIC chest with {coins_from_chest} coins inside!')
        else:
            continue

    elif choice == 's':
        chest_drop = random.randint(1, 2)
        chest_loot = random.choices(chests_rarity, chests_drop_chance)
        x -= move_range
        coins += coins_per_move
        energy -= move_range
        energy += energy_per_move
        moves_made += 1
        if chest_drop == 1:
            if chest_loot == ['basic']:
                coins_from_chest = approximate_value(100)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_basic += 1
                chests_dropped_list[0][1] += 1
                print(
                    f'You have found basic chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['rare']:
                coins_from_chest = approximate_value(200)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_rare += 1
                chests_dropped_list[1][1] += 1
                print(
                    f'You have found rare chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['epic']:
                coins_from_chest = approximate_value(500)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_epic += 1
                chests_dropped_list[2][1] += 1
                print(
                    f'You have found epic chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['legendary']:
                coins_from_chest = approximate_value(750)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_legendary += 1
                chests_dropped_list[3][1] += 1
                print(
                    f'You have found legendary chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['MYTHIC']:
                coins_from_chest = approximate_value(1000)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_MYTHIC += 1
                chests_dropped_list[4][1] += 1
                print(
                    f'You have found MYTHIC chest with {coins_from_chest} coins inside!')
        else:
            continue

    elif choice == 'd':
        chest_drop = random.randint(1, 2)
        chest_loot = random.choices(chests_rarity, chests_drop_chance)
        y += move_range
        coins += coins_per_move
        energy -= move_range
        energy += energy_per_move
        moves_made += 1
        if chest_drop == 1:
            if chest_loot == ['basic']:
                coins_from_chest = approximate_value(100)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_basic += 1
                chests_dropped_list[0][1] += 1
                print(
                    f'You have found basic chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['rare']:
                coins_from_chest = approximate_value(200)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_rare += 1
                chests_dropped_list[1][1] += 1
                print(
                    f'You have found rare chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['epic']:
                coins_from_chest = approximate_value(500)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_epic += 1
                chests_dropped_list[2][1] += 1
                print(
                    f'You have found epic chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['legendary']:
                coins_from_chest = approximate_value(750)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_legendary += 1
                chests_dropped_list[3][1] += 1
                print(
                    f'You have found legendary chest with {coins_from_chest} coins inside.')

            elif chest_loot == ['MYTHIC']:
                coins_from_chest = approximate_value(1000)
                coins += coins_from_chest
                chests_dropped_total += 1
                amount_of_MYTHIC += 1
                chests_dropped_list[4][1] += 1
                print(
                    f'You have found MYTHIC chest with {coins_from_chest} coins inside!')
        else:
            continue

    elif choice == '1':
        show_position()

    elif choice == '2':
        stats()

    elif choice == '3':
        buy_bonus()
        bonusChoice = (input("Your choice: "))
        if bonusChoice == '1':
            if coins > coins_per_move_cost:
                coins -= coins_per_move_cost
                coins_per_move += 5
                coins_per_move_cost += 100
                print('You have successfully bought coins_per_move bonus')
                continue
            else:
                print('Not enough coins.')
                continue

        elif bonusChoice == '2':
            if coins > energy_per_move_cost:
                coins -= energy_per_move_cost
                energy_per_move += 5
                energy_per_move_cost += 100
                print('You have successfully bought energy_per_move bonus')
                continue
            else:
                print('Not enough coins.')
                continue

        elif bonusChoice == '3':
            if coins > chest_drop_chance_cost:
                coins -= chest_drop_chance_cost
                chest_drop_chance += 5
                chest_drop_chance_cost += 100
                print('You have successfully bought chest_drop_chance bonus')
                continue
            else:
                print('Not enough coins.')
                continue

        elif choice == '4':
            continue

    elif choice == '4':
        list_of_bonuses()

    elif choice == '5':
        chest_drops()

    elif choice == '6':
        chests_dropped()

    elif choice == '7':
        endgame = input('Are You sure that You want to finish the game? (y/n)')
        if endgame.lower() == 'y':
            print('Your stats: ')
            stats()
            energy = 0

else:
    print('Out of energy, GAME OVER.')


from aiogram import types, Dispatcher
from start.create_bot import bot, dispetcher, db

@dispetcher.message_handler(commands = ['send_message'])
async def send_message_all_user(message: types.Message):
    users = await db.get_all_user()
    for user in users:
        await bot.send_message(user[0], message.text[13:])

def register_client_handlers(dispetcher: Dispatcher):
    dispetcher.register_message_handler(send_message_all_user, commands = ['send_message'])


import openpyxl
from openpyxl.styles import Font
import datetime
import re

filename = 'spendings.xlsx'

wb = openpyxl.load_workbook(filename)
ws_names = wb.sheetnames

print(wb.sheetnames)

sheetname = input('What sheet do you need? T/O: ')
sheet_index = ws_names.index(sheetname)

wb.active = sheet_index

def counting():

    for col in wb.active.iter_cols(min_row=2, max_row=1000, max_col=4, values_only=True):
        for i, cell in enumerate(col):
            row = i + 1

            if cell is not None:
                None

            else:
                all = input('\nWhat did you buy? ')

                if all == ' ':
                    return row
                else:
                    cost = all.split(' ')
                    cost = int(cost[len(cost) - 1])

                    item = all.replace(str(cost), '')

                    wb.active['A'+str(row)] = item
                    wb.active['B'+str(row)] = cost

                Bold = Font(size=13, bold=True)
                wb.active['D1'].font = Bold
                wb.active['D1'] = 'TOTAL'
                wb.active['D2'] = '=SUM(B1:B100)'

                if (wb.active['A'+str(row)]).value != '.':
                    wb.active['C'+str(row)] = datetime.datetime.strptime("2020/08/11, 14:35", "%Y/%m/%d, %H:%M").now()

                else:
                    wb.active['C'+str(row)] == ' '

    return row

counting()

wb.save(filename)

# я дізнаюся рядок , потімпишу, що купив і додаю у клітинку, пишу ціну і додаю в іншу клітинку
#
# тепер мені потрібно створити змінну row у якій змінюватимуться значення із кожним колом.
# і в кожному колі додавати до row 1 і записувати значення, а якщо хзначення == no або ні
# то переривати програму і все зберігати.