from abc import abstractmethod
from typing import *

from electronics_abstract_parts import *
from .JlcPart import JlcPart

@non_library
class Nrf52840_Interfaces(IoControllerSpiPeripheral, IoControllerI2cTarget, IoControllerUsb, IoControllerI2s,
                          IoControllerBle):
  """Defines base interfaces for nRF52840 microcontrollers"""

@non_library
class Nrf52840_Ios(Nrf52840_Interfaces, BaseIoControllerPinmapGenerator, InternalSubcircuit, GeneratorBlock, FootprintBlock):
  """nRF52840 IO mappings
  https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.7.pdf"""
  RESOURCE_PIN_REMAP: Dict[str, str]  # resource name in base -> pin name

  @abstractmethod
  def _gnd_vddio(self) -> Tuple[Port[VoltageLink], Port[VoltageLink]]:
    ...

  def _vdd_model(self) -> VoltageSink:
    return VoltageSink(
      voltage_limits=(1.75, 3.6)*Volt,  # 1.75 minimum for power-on reset
      current_draw=(0, 212 / 64 + 4.8)*mAmp + self.io_current_draw.upper()  # CPU @ max 212 Coremarks + 4.8mA in RF transmit
    )

  def _dio_model(self, gnd: Port[VoltageLink], pwr: Port[VoltageLink]) -> DigitalBidir:
    return DigitalBidir.from_supply(
      gnd, pwr,
      voltage_limit_tolerance=(-0.3, 0.3) * Volt,
      current_limits=(-6, 6)*mAmp,  # minimum current, high drive, Vdd>2.7
      current_draw=(0, 0)*Amp,
      input_threshold_factor=(0.3, 0.7),
      pullup_capable=True, pulldown_capable=True,
    )

  def _io_pinmap(self) -> PinMapUtil:
    """Returns the mappable for given the input power and ground references.
    This separates the system pins definition from the IO pins definition."""
    gnd, pwr = self._gnd_vddio()
    dio_model = self._dio_model(gnd, pwr)
    dio_lf_model = dio_model  # "standard drive, low frequency IO only" (differences not modeled)

    adc_model = AnalogSink.from_supply(
      gnd, pwr,
      voltage_limit_tolerance=(0, 0),  # datasheet 6.23.2, analog inputs cannot exceed Vdd or be lower than Vss
      signal_limit_tolerance=(0, 0),
      impedance=Range.from_lower(1)*MOhm
    )

    uart_model = UartPort(DigitalBidir.empty())
    spi_model = SpiController(DigitalBidir.empty(), (125, 32000) * kHertz)
    spi_peripheral_model = SpiPeripheral(DigitalBidir.empty(), (125, 32000) * kHertz)  # tristated by CS pin
    i2c_model = I2cController(DigitalBidir.empty())
    i2c_target_model = I2cTarget(DigitalBidir.empty())
    i2s_model = I2sController(DigitalBidir.empty())

    hf_io_pins = [
      'P0.00', 'P0.01', 'P0.26', 'P0.27', 'P0.04',
      'P0.05', 'P0.06', 'P0.07', 'P0.08', 'P1.08', 'P1.09', 'P0.11', 'P0.12',
      'P0.14', 'P0.16', 'P0.19', 'P0.21', 'P0.23', 'P0.25',  # 'P0.18'
      'P0.13', 'P0.15', 'P0.17', 'P0.20', 'P0.22', 'P0.24',  'P1.00',
    ]

    return PinMapUtil([  # Section 7.1.2 with QIAA aQFN73 & QFAA QFN48 pins only
      PinResource('P0.31', {'P0.31': dio_lf_model, 'AIN7': adc_model}),
      PinResource('P0.29', {'P0.29': dio_lf_model, 'AIN5': adc_model}),
      PinResource('P0.02', {'P0.02': dio_lf_model, 'AIN0': adc_model}),
      PinResource('P1.15', {'P1.15': dio_lf_model}),
      PinResource('P1.13', {'P1.13': dio_lf_model}),
      PinResource('P1.10', {'P1.10': dio_lf_model}),
      PinResource('P0.30', {'P0.30': dio_lf_model, 'AIN6': adc_model}),
      PinResource('P0.28', {'P0.28': dio_lf_model, 'AIN4': adc_model}),
      PinResource('P0.03', {'P0.03': dio_lf_model, 'AIN1': adc_model}),
      PinResource('P1.14', {'P1.14': dio_lf_model}),
      PinResource('P1.12', {'P1.12': dio_lf_model}),
      PinResource('P1.11', {'P1.11': dio_lf_model}),
      PinResource('P0.00', {'P0.00': dio_model}),  # TODO also 32.768 kHz crystal in
      PinResource('P0.01', {'P0.01': dio_model}),  # TODO also 32.768 kHz crystal in
      PinResource('P0.26', {'P0.26': dio_model}),
      PinResource('P0.27', {'P0.27': dio_model}),
      PinResource('P0.04', {'P0.04': dio_model, 'AIN2': adc_model}),
      PinResource('P0.10', {'P0.10': dio_lf_model}),  # TODO also NFC2

      PinResource('P0.05', {'P0.05': dio_model, 'AIN3': adc_model}),
      PinResource('P0.06', {'P0.06': dio_model}),
      PinResource('P0.09', {'P0.09': dio_lf_model}),  # TODO also NFC1
      PinResource('P0.07', {'P0.07': dio_model}),
      PinResource('P0.08', {'P0.08': dio_model}),
      PinResource('P1.08', {'P1.08': dio_model}),
      PinResource('P1.07', {'P1.07': dio_lf_model}),
      PinResource('P1.09', {'P1.09': dio_model}),
      PinResource('P1.06', {'P1.06': dio_lf_model}),
      PinResource('P0.11', {'P0.11': dio_model}),
      PinResource('P1.05', {'P1.05': dio_lf_model}),
      PinResource('P0.12', {'P0.12': dio_model}),
      PinResource('P1.04', {'P1.04': dio_lf_model}),
      PinResource('P1.03', {'P1.03': dio_lf_model}),
      PinResource('P1.02', {'P1.02': dio_lf_model}),
      PinResource('P1.01', {'P1.01': dio_lf_model}),
      PinResource('P0.14', {'P0.14': dio_model}),
      PinResource('P0.16', {'P0.16': dio_model}),
      # PinResource('P0.18', {'P0.18': dio_model}),  # configurable as RESET, mappable
      PinResource('P0.19', {'P0.19': dio_model}),
      PinResource('P0.21', {'P0.21': dio_model}),
      PinResource('P0.23', {'P0.23': dio_model}),
      PinResource('P0.25', {'P0.25': dio_model}),

      PinResource('P0.13', {'P0.13': dio_model}),
      PinResource('P0.15', {'P0.15': dio_model}),
      PinResource('P0.17', {'P0.17': dio_model}),
      PinResource('P0.20', {'P0.20': dio_model}),
      PinResource('P0.22', {'P0.22': dio_model}),
      PinResource('P0.24', {'P0.24': dio_model}),
      PinResource('P1.00', {'P1.00': dio_model}),  # TRACEDATA[0] and SWO, if used as IO must clear TRACECONFIG reg

      PeripheralFixedPin('SWD', SwdTargetPort(dio_model), {
        'swclk': 'SWCLK', 'swdio': 'SWDIO',
      }),
      PeripheralFixedPin('USBD', UsbDevicePort(), {
        'dp': 'D+', 'dm': 'D-'
      }),

      PeripheralFixedResource('SPIM0', spi_model, {
        'sck': hf_io_pins, 'miso': hf_io_pins, 'mosi': hf_io_pins,
      }),
      PeripheralFixedResource('SPIM1', spi_model, {
        'sck': hf_io_pins, 'miso': hf_io_pins, 'mosi': hf_io_pins,
      }),
      PeripheralFixedResource('SPIM2', spi_model, {
        'sck': hf_io_pins, 'miso': hf_io_pins, 'mosi': hf_io_pins,
      }),
      PeripheralFixedResource('SPIM3', spi_model, {
        'sck': hf_io_pins, 'miso': hf_io_pins, 'mosi': hf_io_pins,
      }),
      PeripheralFixedResource('SPIS0', spi_peripheral_model, {  # TODO shared resource w/ SPI controller
        'sck': hf_io_pins, 'miso': hf_io_pins, 'mosi': hf_io_pins,
      }),
      PeripheralFixedResource('SPIS1', spi_peripheral_model, {  # TODO shared resource w/ SPI controller
        'sck': hf_io_pins, 'miso': hf_io_pins, 'mosi': hf_io_pins,
      }),
      PeripheralFixedResource('SPIS2', spi_peripheral_model, {  # TODO shared resource w/ SPI controller
        'sck': hf_io_pins, 'miso': hf_io_pins, 'mosi': hf_io_pins,
      }),
      PeripheralFixedResource('TWIM0', i2c_model, {
        'scl': hf_io_pins, 'sda': hf_io_pins,
      }),
      PeripheralFixedResource('TWIM1', i2c_model, {
        'scl': hf_io_pins, 'sda': hf_io_pins,
      }),
      PeripheralFixedResource('TWIS0', i2c_target_model, {  # TODO shared resource w/ I2C controller
        'scl': hf_io_pins, 'sda': hf_io_pins,
      }),
      PeripheralFixedResource('TWIS1', i2c_target_model, {  # TODO shared resource w/ I2C controller
        'scl': hf_io_pins, 'sda': hf_io_pins,
      }),
      PeripheralFixedResource('UARTE0', uart_model, {
        'tx': hf_io_pins, 'rx': hf_io_pins,
      }),
      PeripheralFixedResource('UARTE1', uart_model, {
        'tx': hf_io_pins, 'rx': hf_io_pins,
      }),
      PeripheralFixedResource('I2S', i2s_model, {
        'sck': hf_io_pins, 'ws': hf_io_pins, 'sd': hf_io_pins,
      }),
    ]).remap_pins(self.RESOURCE_PIN_REMAP)

@abstract_block
class Nrf52840_Base(Nrf52840_Ios, InternalSubcircuit, GeneratorBlock):
  SYSTEM_PIN_REMAP: Dict[str, Union[str, List[str]]]  # pin name in base -> pin name(s)

  def _gnd_vddio(self) -> Tuple[Port[VoltageLink], Port[VoltageLink]]:
    return self.gnd, self.pwr

  def _system_pinmap(self) -> Dict[str, CircuitPort]:
    return VariantPinRemapper({
      'Vdd': self.pwr,
      'Vss': self.gnd,
      'Vbus': self.pwr_usb,
      'nRESET': self.nreset,
    }).remap(self.SYSTEM_PIN_REMAP)

  def __init__(self, **kwargs) -> None:
    super().__init__(**kwargs)

    self.pwr = self.Port(self._vdd_model(), [Power])
    self.gnd = self.Port(Ground(), [Common])

    self.pwr_usb = self.Port(VoltageSink(
      voltage_limits=(4.35, 5.5)*Volt,
      current_draw=(0.262, 7.73) * mAmp  # CPU/USB sleeping to everything active
    ), optional=True)
    self.require((self.usb.length() > 0).implies(self.pwr_usb.is_connected()), "USB require Vbus connected")

    # Additional ports (on top of IoController)
    # Crystals from table 15, 32, 33
    # TODO Table 32, model crystal load capacitance and series resistance ratings
    self.xtal = self.Port(CrystalDriver(frequency_limits=(1, 25)*MHertz, voltage_out=self.pwr.link().voltage),
                          optional=True)
    # Assumed from "32kHz crystal" in 14.5
    self.xtal_rtc = self.Port(CrystalDriver(frequency_limits=(32, 33)*kHertz, voltage_out=self.pwr.link().voltage),
                              optional=True)

    self.swd = self.Port(SwdTargetPort.empty())
    self.nreset = self.Port(DigitalSink.from_bidir(self._dio_model(self.gnd, self.pwr)), optional=True)
    self._io_ports.insert(0, self.swd)

class Holyiot_18010_Device(Nrf52840_Base):
  SYSTEM_PIN_REMAP: Dict[str, Union[str, List[str]]] = {
    'Vdd': '14',
    'Vss': ['1', '25', '37'],
    'Vbus': '22',
    'nRESET': '21',
  }
  RESOURCE_PIN_REMAP = {  # boundary pins only, inner pins ignored
    'P1.11': '2',
    'P1.10': '3',
    'P1.13': '4',
    'P1.15': '5',
    'P0.03': '6',
    'P0.02': '7',
    'P0.28': '8',
    'P0.29': '9',
    'P0.30': '10',
    'P0.31': '11',
    'P0.04': '12',
    'P0.05': '13',

    'P0.07': '15',
    'P1.09': '16',
    'P0.12': '17',
    'P0.23': '18',
    'P0.21': '19',
    'P0.19': '20',
    'D-': '23',
    'D+': '24',

    'P0.22': '26',
    'P1.00': '27',
    'P1.03': '28',
    'P1.01': '29',
    'P1.02': '30',
    'SWCLK': '31',
    'SWDIO': '32',
    'P1.04': '33',
    'P1.06': '34',
    'P0.09': '35',
    'P0.10': '36',
  }

  def generate(self) -> None:
    super().generate()

    self.footprint(
      'U', 'edg:Holyiot-18010-NRF52840',
      self._make_pinning(),
      mfr='Holyiot', part='18010',
      datasheet='http://www.holyiot.com/tp/2019042516322180424.pdf'
    )

class Holyiot_18010(Microcontroller, Radiofrequency, Resettable, Nrf52840_Interfaces, IoControllerWithSwdTargetConnector,
                    IoControllerPowerRequired, BaseIoControllerExportable, GeneratorBlock):
  """Wrapper around the Holyiot 18010 that includes supporting components (programming port)"""
  def __init__(self, **kwargs):
    super().__init__(**kwargs)
    self.ic: Holyiot_18010_Device
    self.ic = self.Block(Holyiot_18010_Device(pin_assigns=ArrayStringExpr()))
    self.pwr_usb = self.Export(self.ic.pwr_usb, optional=True)
    self.generator_param(self.reset.is_connected())

  def contents(self):
    super().contents()
    self.connect(self.pwr, self.ic.pwr)
    self.connect(self.gnd, self.ic.gnd)

    self.connect(self.swd_node, self.ic.swd)
    self.connect(self.reset_node, self.ic.nreset)

  def generate(self):
    super().generate()
    if self.get(self.reset.is_connected()):
      self.connect(self.reset, self.ic.nreset)

class Mdbt50q_1mv2_Device(Nrf52840_Base, JlcPart):
  SYSTEM_PIN_REMAP: Dict[str, Union[str, List[str]]] = {
    'Vdd': ['28', '30'],  # 28=Vdd, 30=VddH; 31=DccH is disconnected - from section 8.3 for input voltage <3.6v
    'Vss': ['1', '2', '15', '33', '55'],
    'Vbus': '32',
    'nRESET': '40',
  }
  RESOURCE_PIN_REMAP = {  # boundary pins only, inner pins ignored
    'P1.10': '3',
    'P1.11': '4',
    'P1.12': '5',
    'P1.13': '6',
    'P1.14': '7',
    'P1.15': '8',
    'P0.03': '9',
    'P0.29': '10',
    'P0.02': '11',
    'P0.31': '12',
    'P0.28': '13',
    'P0.30': '14',

    'P0.27': '16',
    'P0.00': '17',
    'P0.01': '18',
    'P0.26': '19',
    'P0.04': '20',
    'P0.05': '21',
    'P0.06': '22',
    'P0.07': '23',
    'P0.08': '24',
    'P1.08': '25',
    'P1.09': '26',
    'P0.11': '27',
    'P0.12': '29',
    'D-': '34',
    'D+': '35',

    'P0.14': '36',
    'P0.13': '37',
    'P0.16': '38',
    'P0.15': '39',
    'P0.17': '41',
    'P0.19': '42',
    'P0.21': '43',
    'P0.20': '44',
    'P0.23': '45',
    'P0.22': '46',
    'P1.00': '47',
    'P0.24': '48',
    'P0.25': '49',
    'P1.02': '50',
    'SWDIO': '51',
    'P0.09': '52',
    'SWCLK': '53',
    'P0.10': '54',

    'P1.04': '56',
    'P1.06': '57',
    'P1.07': '58',
    'P1.05': '59',
    'P1.03': '60',
    'P1.01': '61',
  }

  def generate(self) -> None:
    super().generate()

    self.assign(self.lcsc_part, 'C5118826')
    self.assign(self.actual_basic_part, False)
    self.footprint(
      'U', 'RF_Module:Raytac_MDBT50Q',
      self._make_pinning(),
      mfr='Raytac', part='MDBT50Q-1MV2',
      datasheet='https://www.raytac.com/download/index.php?index_id=43'
    )

class Mdbt50q_UsbSeriesResistor(InternalSubcircuit, Block):
  def __init__(self):
    super().__init__()
    self.usb_inner = self.Port(UsbHostPort.empty(), [Input])
    self.usb_outer = self.Port(UsbDevicePort.empty(), [Output])
    self.res_dp = self.Block(Resistor(27*Ohm(tol=0.01)))
    self.res_dm = self.Block(Resistor(27*Ohm(tol=0.01)))
    self.connect(self.usb_inner.dp, self.res_dp.a.adapt_to(DigitalBidir()))  # TODO propagate params - needs bridge mechanism
    self.connect(self.usb_outer.dp, self.res_dp.b.adapt_to(DigitalBidir()))
    self.connect(self.usb_inner.dm, self.res_dm.a.adapt_to(DigitalBidir()))
    self.connect(self.usb_outer.dm, self.res_dm.b.adapt_to(DigitalBidir()))

class Mdbt50q_1mv2(Microcontroller, Radiofrequency, Resettable, Nrf52840_Interfaces, IoControllerWithSwdTargetConnector,
                   IoControllerPowerRequired, BaseIoControllerExportable, GeneratorBlock):
  """Wrapper around the Mdbt50q_1mv2 that includes the reference schematic"""
  def __init__(self, **kwargs):
    super().__init__(**kwargs)
    self.ic: Mdbt50q_1mv2_Device
    self.ic = self.Block(Mdbt50q_1mv2_Device(pin_assigns=ArrayStringExpr()))  # defined in generator to mix in SWO/TDI
    self.pwr_usb = self.Export(self.ic.pwr_usb, optional=True)
    self.generator_param(self.reset.is_connected())

  def contents(self) -> None:
    super().contents()
    self.connect(self.pwr, self.ic.pwr)
    self.connect(self.gnd, self.ic.gnd)

    self.connect(self.swd_node, self.ic.swd)
    self.connect(self.reset_node, self.ic.nreset)

    with self.implicit_connect(
        ImplicitConnect(self.pwr, [Power]),
        ImplicitConnect(self.gnd, [Common])
    ) as imp:
      self.vcc_cap = imp.Block(DecouplingCapacitor(10 * uFarad(tol=0.2)))

  def generate(self):
    super().generate()

    if self.get(self.reset.is_connected()):
      self.connect(self.reset, self.ic.nreset)

  ExportType = TypeVar('ExportType', bound=Port)
  def _make_export_vector(self, self_io: ExportType, inner_vector: Vector[ExportType], name: str,
                          assign: Optional[str]) -> Optional[str]:
    if isinstance(self_io, UsbDevicePort):  # assumed at most one USB port generates
      inner_io = inner_vector.request(name)
      (self.usb_res, ), self.usb_chain = self.chain(inner_io, self.Block(Mdbt50q_UsbSeriesResistor()), self_io)
      self.vbus_cap = self.Block(DecouplingCapacitor(10 * uFarad(tol=0.2))).connected(self.gnd, self.pwr_usb)
      return assign
    return super()._make_export_vector(self_io, inner_vector, name, assign)

class Feather_Nrf52840(IoControllerUsbOut, IoControllerPowerOut, Nrf52840_Ios, IoController, GeneratorBlock,
                       FootprintBlock):
  """Feather nRF52840 socketed dev board as either power source or sink"""

  SYSTEM_PIN_REMAP: Dict[str, Union[str, List[str]]] = {
    'Vdd': '2',  # 3v3
    'Vss': '4',

    # 'reset': '1',
    'Vbus': '26',
    # 'EN': '27',  # controls the onboard 3.3 LDO, internally pulled up
    # 'Vbat': '28',
  }
  RESOURCE_PIN_REMAP = {  # boundary pins only, inner pins ignored
    'P0.31': '3',  # AREF
    'P0.04': '5',  # A0
    'P0.05': '6',  # A1
    'P0.30': '7',  # A2
    'P0.28': '8',  # A3
    'P0.02': '9',  # A4
    'P0.03': '10',  # A5
    'P0.14': '11',  # SCK
    'P0.13': '12',  # MOSI
    'P0.15': '13',  # MISO
    'P0.24': '14',  # RXD
    'P0.25': '15',  # TXD
    'P0.10': '16',  # D2

    'P0.12': '17',  # SDA
    'P0.11': '18',  # SCL
    'P1.08': '19',  # D5
    'P0.07': '20',  # D6
    'P0.26': '21',  # D9
    'P0.27': '22',  # D10
    'P0.06': '23',  # D11
    'P0.08': '24',  # D12
    'P1.09': '25',  # D13

    # note onboard LED1 at P1.15, LED2 at P1.10
    # note onboard switch at P1.02, reset switch at P0.18
    # note onboard neopixel at P0.16 (data out not broken out)
    # note onboard VBAT sense divider at P0.29
  }

  def _gnd_vddio(self) -> Tuple[Port[VoltageLink], Port[VoltageLink]]:
    if self.get(self.gnd.is_connected()):  # board sinks power
      return self.gnd, self.pwr
    else:
      return self.gnd_out, self.pwr_out

  def _system_pinmap(self) -> Dict[str, CircuitPort]:
    if self.get(self.gnd.is_connected()):  # board sinks power
      self.require(~self.vusb_out.is_connected(), "can't source USB power if source gnd not connected")
      self.require(~self.pwr_out.is_connected(), "can't source 3v3 power if source gnd not connected")
      self.require(~self.gnd_out.is_connected(), "can't source gnd if source gnd not connected")
      return VariantPinRemapper({
        'Vdd': self.pwr,
        'Vss': self.gnd,
      }).remap(self.SYSTEM_PIN_REMAP)
    else:  # board sources power (default)
      self.require(~self.pwr.is_connected(), "can't sink power if source gnd connected")
      self.require(~self.gnd.is_connected(), "can't sink gnd if source gnd connected")
      return VariantPinRemapper({
        'Vdd': self.pwr_out,
        'Vss': self.gnd_out,
        'Vbus': self.vusb_out,
      }).remap(self.SYSTEM_PIN_REMAP)

  def contents(self):
    super().contents()

    self.gnd.init_from(Ground())
    self.pwr.init_from(self._vdd_model())

    mbr120_drop = (0, 0.340)*Volt
    ap2112_3v3_out = 3.3*Volt(tol=0.015)  # note dropout voltage up to 400mV, current up to 600mA
    self.gnd_out.init_from(GroundSource())
    self.vusb_out.init_from(VoltageSource(
      voltage_out=UsbConnector.USB2_VOLTAGE_RANGE - mbr120_drop,
      current_limits=UsbConnector.USB2_CURRENT_LIMITS
    ))
    self.pwr_out.init_from(VoltageSource(
      voltage_out=ap2112_3v3_out,
      current_limits=UsbConnector.USB2_CURRENT_LIMITS
    ))

    self.generator_param(self.gnd.is_connected())

  def generate(self) -> None:
    super().generate()

    self.footprint(
      'U', 'bldc:FEATHERWING_NODIM',
      self._make_pinning(),
      mfr='Adafruit', part='Feather nRF52840 Express',
      datasheet='https://learn.adafruit.com/assets/68545'
    )


class Solution:
    def moveZeroes_slow(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        count = 0
        length = len(nums)
        i = 0
        while i != length - count:
            print('i=',i,':',nums[i])
            if nums[i] == 0:
                count += 1
                for j in range(i,length - 1):
                    nums[j] = nums[j+1]
                i -= 1
            i += 1
            print(nums)

        for i in range(count):
            # print('i:',i)
            nums[length-i-1] = 0
        # print(nums)

    def moveZeroes_v2(self, nums):
        n = len(nums)
        i = -1
        j = 0
        # nums[0....i]表示非0元素的数列,初始值i=-1
        while j <= n-1:
            if nums[j] != 0:
                i += 1
                nums[i] = nums[j]
            j += 1
        for k in range(i+1, n):
            nums[k] = 0

    def moveZeroes(self,nums):
        n = len(nums)
        i = -1
        j = 0
        while j < n:
            if nums[j] != 0:
                i += 1
                nums[i] = nums[j]
            j += 1
        for k in range(i+1,n):
            nums[k] = 0
        print(nums)

#different from c
# for i in range(10):
#     print(i)
#     if i == 5:
#         i -= 1

array = [2,2,0,2,21,1,1,3,3,1,0]
print(array)

s1 = Solution()
s1.moveZeroes(array)
print(array)


"""
All models for core app are defined here.
"""
from django.conf import settings
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.shortcuts import reverse
from django_countries.fields import CountryField

class Actor(models.Model):
    """
    Actor model.
    """
    name = models.CharField(max_length=100)  # Name of the actor

    class Meta:
        ordering = ["name"]  # Order actors by name

    def __str__(self):
        return self.name

class Director(models.Model):
    """
    Director model.
    """
    name = models.CharField(max_length=100)  # Name of the director

    class Meta:
        ordering = ["name"]  # Order directors by name

    def __str__(self):
        return self.name

class Genre(models.Model):
    """
    Genre model.
    """
    name = models.CharField(max_length=100)  # Name of the genre

    class Meta:
        ordering = ["name"]  # Order genres by name

    def __str__(self):
        return self.name

class Movie(models.Model):
    """
    Movie model.
    """

    title = models.CharField(max_length=100)  # Title of the movie
    runtime = models.IntegerField(blank=True, null=True)  # Movie runtime
    year = models.IntegerField()  # Release year of the movie
    description = models.TextField(null=True)  # Basic movie description

    # IMDb rating for the movie
    rating = models.DecimalField(decimal_places=1, max_digits=2)
    genre = models.ManyToManyField(Genre)  # Movie genres, foreign key to Genre

    # Movie director, foreign key to Director
    directors = models.ManyToManyField(Director)

    # Movie actors, foreign key to Actor
    actors = models.ManyToManyField(Actor)
    certificate = models.TextField(max_length=4)  # Age rating for the movie
    icon_url = models.SlugField(max_length=220, null=True)
    poster_url = models.SlugField(max_length=220, null=True)
    big_poster_url = models.SlugField(max_length=220, null=True)

    class Meta:
        ordering = ["runtime"]  # Order movies by runtime

    def get_absolute_url(self):
        """
        Returns the url to access a particular instance of the model.
        """
        return reverse("core:movie", kwargs={
            "pk": self.pk
        })

    def get_add_to_cart_url(self):
        """
        Returns the url to add the movie to cart.
        """
        return reverse("core:add-to-cart", kwargs={
            "pk": self.pk
        })

    def get_remove_from_cart_url(self):
        """
        Returns the url to add the movie to cart.
        """
        return reverse("core:remove-from-cart", kwargs={
            "pk": self.pk
        })

    def get_add_to_wishlist_url(self):
        """
        Returns the url to add the movie to cart.
        """
        return reverse("core:add-to-wishlist", kwargs={
            "pk": self.pk
        })

    def get_remove_from_wishlist_url(self):
        """
        Returns the url to add the movie to cart.
        """
        return reverse("core:remove-from-wishlist", kwargs={
            "pk": self.pk
        })

    def __str__(self):
        return self.title

class OrderItem(models.Model):
    """
    Links the Movie model. When a Movie object is added to the cart it becomes an OrderItem object.
    """
    # User who added the movie to the cart
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE)
    item = models.ForeignKey(Movie, on_delete=models.CASCADE)
    ordered = models.BooleanField(default=False)  # If the order is completed

    DURATION_CHOICES = [
        ("D", "One Day"),
        ("W", "One Week"),
        ("P", "Permanent"),
    ]
    duration = models.CharField(
        max_length=1,
        choices=DURATION_CHOICES,
        default="D"
    )

    price = models.DecimalField(  # Price of the movie
        max_digits=5,
        decimal_places=2,
        default=100.00,
    )

    def __str__(self):
        return f"{self.item.title} rented for {self.get_duration_display()}"

    def save(self, *args, **kwargs):
        """
        Overriding default save() function to set price dynamically.
        """
        if self.duration == "P":
            self.price = 300.00
        elif self.duration == "W":
            self.price = 200.00
        else:
            self.price = 100.00

        super().save(*args, **kwargs)

class Order(models.Model):
    """Stores all the movies in the cart. Can be thought of as the model for the User's cart."""
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE
    )  # User who made the order

    items = models.ManyToManyField(OrderItem)  # Movies in the cart

    start_date = models.DateTimeField(
        auto_now_add=True
    )  # Date when the order was started

    ordered_date = models.DateTimeField()  # Date when the order was confirmed

    ordered = models.BooleanField(default=False)  # If the order is completed

    address = models.ForeignKey(
        "Address", on_delete=models.SET_NULL, blank=True, null=True)

    def __str__(self):
        return f"{self.id}: {self.start_date}"

    def get_total(self):
        """
        Returns the total price of the order.
        """
        total = 0
        for order_item in self.items.all():
            total += order_item.price
        return total

class Address(models.Model):
    """The address model."""
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )
    address1 = models.CharField(max_length=100)
    address2 = models.CharField(max_length=100)
    country = CountryField(multiple=False)
    pincode = models.CharField(max_length=100)
    default = models.BooleanField(default=False)

    def __str__(self) -> str:
        return self.user.username

class WishlistItem(models.Model):
    """Add movies to wishlist"""
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE)
    item = models.ForeignKey(Movie, on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.item.title}"

class Wishlist(models.Model):
    """Stores all movies in wishlist"""
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE
    )  # User who added to the wishlist

    items = models.ManyToManyField(WishlistItem)  # Movies in the wishlist

class Profile(models.Model):
    """
    User profile model.
    """
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    phone_number = models.CharField(max_length=10, blank=True)
    profile_pic = models.ImageField(
        upload_to="profile_pics/", blank=True, null=True)

    def __str__(self):
        return self.user.username

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_profile(sender, instance=None, created=False, **kwargs):
    """
    Create a profile for the user when user is created.
    """
    if created:
        Profile.objects.create(user=instance)


from os import path
import pygame.sprite

class Boss(pygame.sprite.Sprite):
    def __init__(self,level):
        pygame.sprite.Sprite.__init__(self)
        #self.image = pygame.Surface([500, 500])
        self.width = 200
        self.height = 100
        self.level = 0
        self.id = "boss1"
        if level == 0:
            self.width = 200
            self.height = 100
            self.hp = 30
            self.level = 0
            self.id = "boss1"
        elif level == 1:
            self.width = 150
            self.height = 200
            self.hp = 60
            self.level = 1
            self.id = "boss2"
        elif level == 2:
            self.width = 200
            self.height = 100
            self.hp = 90
            self.level = 2
            self.id = "boss3"

        self.image = pygame.Surface([self.width, self.height])
        self.color = "#FFEB3B"
        self.rect = self.image.get_rect()
        self.rect.center = (600, 80)

        self.dir = 10
        self.bullets = pygame.sprite.Group()
        self.times_up = 3
        self.counter = 0
        self.hp = 100

    def get_bullets(self):
        return self.bullets

    def _gen_bullets(self, count: int = 1, gap:int = 0, y:int = 0, speed:int = 10.5):
        sum = 0
        for i in range(count):
            # add food to group
            bullet = Bullet(self.bullets, self.rect.centerx, self.rect.centery+sum, 0, y, speed)
            sum += gap

    def _gen_bullets_side(self, count: int = 1, gap:int = 0, y:int = 0, speed:int = 10.5):
        sum = 0
        for i in range(count):
            # add food to group
            bullet = Bullet(self.bullets, self.rect.centerx+self.width/2, self.rect.centery+sum, 0, y, speed)
            bullet = Bullet(self.bullets, self.rect.centerx-self.width/2, self.rect.centery+sum, 0, y, speed)
            sum += gap

    def recycle(self,items):
        for item in items:
            if(item.rect.centery < 0 or item.rect.centery > 600 or item.rect.centerx < 0 or item.rect.centerx > 600):
                items.remove(item)

        return items

    def _fire(self, times_up, b_num, gap, y:int = 0, speed:int = 10.5, side:bool = False):
        if side:
            if(self.counter % times_up == 0):
                self._gen_bullets_side(b_num, gap, y, speed)
        else:
            if(self.counter % times_up == 0):
                self._gen_bullets(b_num, gap, y, speed)

    def update(self):
        #body
        self.rect.centerx += self.dir
        if(self.rect.centerx < 0 or self.rect.centerx > 1280):
            self.dir = -self.dir

        #bullet
        self.counter +=1
        self._fire(10,1, 0)
        if self.level >= 1:
            self._fire(30,30, 7, 300, 30)
        if self.level >= 2:
            self._fire(15,15, 7, 100, 50, True)

        #self.recycle(self.bullets)

    @property
    def game_object_data(self):
        return {"type": "image",
                "x": self.rect.x,
                "y": self.rect.y,
                "angle": 0,
                "width": self.rect.width,
                "height": self.rect.height,
                "image_id": self.id
                }

class Bullet(pygame.sprite.Sprite):
    def __init__(self, group, x, y, dir, speed_up_y:int = 0, speed: int = 10.5):
        pygame.sprite.Sprite.__init__(self, group)
        self.image = pygame.Surface([8, 8])
        self.color = "#FF90A0"
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = y
        self.angle = 0
        self.dir = dir
        self.speed = 10.5
        self.speed_up_y = speed_up_y
        self.changeSpeed = speed

    def update(self) -> None:
        if(self.speed_up_y > 0 and self.rect.centery > self.speed_up_y):
            self.rect.centery += self.changeSpeed
        else:
            self.rect.centery += self.speed

    @property
    def game_object_data(self):
        return {"type": "rect",
                "name": "ball",
                "x": self.rect.x,
                "y": self.rect.y,
                "angle": 0,
                "width": self.rect.width,
                "height": self.rect.height,
                "color": self.color
                }


# This program will calculate the average of 5 test scores
# 6.27.2017
# CTI-110 M5HW1 - Test Average and Grade
# YOlanda McNeill
#

def main():
    print('Please enter 5 test scores.')
    score1 = int(input('Enter the test score: '))
    score2 = int(input('Enter the test score: '))
    score3 = int(input('Enter the test score: '))
    score4 = int(input('Enter the test score: '))
    score5 = int(input('Enter the test score: '))

    print('score 1:', determine_grade(score1))
    print('score 2:', determine_grade(score2))
    print('score 3:', determine_grade(score3))
    print('score 4:', determine_grade(score4))
    print('score 5:', determine_grade(score5))

    print('average: ',calc_average(score1, score2, score3, score4, score5))

def calc_average(score1, score2, score3, score4, score5):
    total = score1 + score2 + score3 + score4 + score5
    average = total / 5

    return average

def determine_grade(score):
    if score >= 90:
        letterGrade = 'A'
        return letterGrade

    else:
        if score > 79 and score <= 89:
            letterGrade = 'B'
            return letterGrade

        else:
            if score > 69 and score <= 79:
                letterGrade = 'C'
                return letterGrade

            else:
                if score > 59 and score <= 69:
                    letterGrade = 'D'
                    return letterGrade

                else:
                    letterGrade = 'F'

                return letterGrade

main()


from pymysql.err import IntegrityError
from fastapi import Request, status
from fastapi.responses import JSONResponse

class HasUsedException(Exception):
    """
    参数值与数据库中数据重复，已被使用
    """
    def __init__(self, name, value=None):
        self.name = name
        self.value = value

async def has_used_exception_handler(request: Request, exc: HasUsedException):
    if exc.value is not None:
        message = f'"{exc.value}",the value of param "{exc.name}",has been used'
    else:
        message = f'The value of param "{exc.name}" has been used'
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content={'detail': message}
    )

async def integrity_error_handler(request: Request, exc: IntegrityError):
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content={'detail': str(exc)}
    )


from DeviceCustomizer import *
from tools import *

class StepMotorDevCustomizer(DeviceCustomizer):
    def __init__(self, mcu_hw, dev_configs, common_config):
        super().__init__(mcu_hw, dev_configs, common_config, "STEP_MOTOR")
        self.hlek_lib_common_header, self.shared_header, self.fw_header, self.sw_header, self.shared_token = common_config["generation"]["shared"][self.__class__.__name__]
        self.sw_lib_header = "step_motor_conf.hpp"
        self.sw_lib_source = "step_motor_conf.cpp"

        self.add_template(os.path.join(self.fw_inc_templ, self.fw_header),
                          [os.path.join(self.fw_inc_dest, self.fw_header)])
        self.add_template(os.path.join(self.sw_inc_templ, self.hlek_lib_common_header),
                          [os.path.join(self.libhlek_inc_dest_path, self.hlek_lib_common_header)])

        self.add_template(os.path.join(self.sw_lib_inc_templ_path, self.sw_lib_header),
                          [os.path.join(self.sw_lib_inc_dest, self.sw_lib_header)])
        self.add_template(os.path.join(self.sw_lib_src_templ_path, self.sw_lib_source),
                          [os.path.join(self.sw_lib_src_dest, self.sw_lib_source)])

        self.add_shared_code(os.path.join(self.shared_templ, self.shared_header),
                             self.shared_token)

    def customize(self):
        indx = 0
        fw_device_descriptors = ["#define STEP_MOTOR_DEVICE_DESCRIPTORS \\"]
        fw_motor_buffers = ["#define STEP_MOTORS_BUFFERS \\"]
        fw_motor_dev_counts = []
        fw_dev_status_buffers = ["#define STEP_MOTOR_DEV_STATUS_BUFFER \\"]
        fw_dev_status_buffer_names = []
        timer_irq_handler_list = []
        fw_motor_descriptors = ["#define STEP_MOTOR_MOTOR_DESCRIPTORS \\"]
        fw_motor_descriptor_arrays = ["#define STEP_MOTOR_MOTOR_DESCRIPTOR_ARRAYS \\"]
        fw_motor_context_arrays = ["#define STEP_MOTOR_MOTOR_CONTEXT_ARRAYS \\"]
        fw_motor_status_arrays = ["#define STEP_MOTOR_MOTOR_STATUS_ARRAYS \\"]
        fw_devices_array = []
        sw_motor_descriptors = []
        sw_motor_descriptor_arrays = []
        sw_devices_descriptors = []
        sw_config_array_name = "step_motor_configs"
        sw_config_declarations = []
        sw_configs = []

        for dev_name, dev_config in self.device_list:
            self.require_feature("SYSTICK", dev_config)
            dev_id = dev_config["dev_id"]
            motors_cfg = dev_config["motors"]
            dev_requires = dev_config["requires"]
            motors_count = len(motors_cfg)
            timer = self.get_timer(dev_requires)
            timer_irq_handler = self.mcu_hw.TIMER_to_IRQHandler(timer)
            timer_irqn = self.mcu_hw.ISRHandler_to_IRQn(timer_irq_handler)
            dev_descriptor_name = "g_" + dev_name.lower() + "_devices"
            dev_motor_descr_list = []
            sw_dev_motor_descr_list = []

            timer_irq_handler_list.append(
                "MAKE_ISR_WITH_INDEX({0}, STEP_MOTOR_COMMON_TIMER_IRQ_HANDLER, {1}) \\".format(timer_irq_handler, indx))
            dev_requires[dev_name + "_irq_handler"] = {"irq_handler": timer_irq_handler}

            # motor count defines
            dev_mcount_def = "STEP_MOTOR_" + dev_name.upper() + "_MOTOR_COUNT"
            dev_mstatus_size = "STEP_MOTOR_" + dev_name.upper() + "_STATUS_SIZE"
            fw_motor_dev_counts.append("#define {0} ({1})".format(dev_mcount_def, motors_count))
            fw_motor_dev_counts.append(
                "#define {0} (sizeof(StepMotorDevStatus) + {1}*sizeof(StepMotorStatus))".format(dev_mstatus_size,
                                                                                dev_mcount_def))

            # motor status structures
            dev_status_name = "g_" + dev_name.lower() + "_status_buffer"
            fw_dev_status_buffers.append(
                "volatile uint8_t {0}[{1}] = {{0}}; \\".format(dev_status_name, dev_mstatus_size))
            fw_dev_status_buffer_names = []

            for mot_name, mot_cfg in motors_cfg.items():
                mot_var_prefix = "g_" + dev_name.lower() + "_" + mot_name.lower()

                # Drive type
                drive_type = self.get_drive_type(mot_name, mot_cfg, dev_name)

                used_pins = self.get_driver_gpio(mot_name, mot_cfg, dev_name, dev_requires)
                # Motor buffers
                mot_buf_size = int(mot_cfg["buffer_size"])
                mot_buffer_name = mot_var_prefix + "_buffer"
                fw_motor_buffers.append(self.tab + "uint8_t {0}[{1}] = {{0}}; \\".format(mot_buffer_name, mot_buf_size))

                # Motor default speed
                default_speed = int(mot_cfg.get("default_speed", 1000000))

                # Motor descriptors
                mot_descriptor_name = mot_var_prefix + "_descriptor"
                mot_descriptor = self.get_motor_description(True, used_pins, mot_name, mot_cfg, dev_name, dev_requires,
                                                            mot_buffer_name, mot_buf_size, default_speed, drive_type)
                fw_motor_descriptors.append(
                    "volatile StepMotorDescriptor {0} = {{ {1} }}; \\".format(mot_descriptor_name, mot_descriptor))
                dev_motor_descr_list.append("&" + mot_descriptor_name)
                sw_dev_motor_descr_list.append("&" + mot_descriptor_name)

                mot_descriptor = self.get_motor_description(False, used_pins, mot_name, mot_cfg, dev_name, dev_requires,
                                                            mot_buffer_name, mot_buf_size, default_speed, drive_type)
                sw_motor_descriptors.append(
                    "const StepMotorDescriptor {0} = {{ {1} }};".format(mot_descriptor_name, mot_descriptor))

            # Motor descriptors
            motor_descriptors_array_name = "g_" + dev_name.lower() + "_motor_descriptors"
            fw_motor_descriptor_arrays.append(
                "volatile StepMotorDescriptor* {0}[] = {{ {1} }};\\".format(motor_descriptors_array_name,
                                                                            ", ".join(dev_motor_descr_list)))
            sw_motor_descriptor_arrays.append(
                "const StepMotorDescriptor* {0}[] = {{ {1} }};".format(motor_descriptors_array_name,
                                                                           ", ".join(sw_dev_motor_descr_list)))

            # Motor contexts
            motor_context_arrays_name = "g_" + dev_name.lower() + "_motor_contexts"
            fw_motor_context_arrays.append(
                "volatile StepMotorContext {0}[{1}] = {{0}}; \\".format(motor_context_arrays_name, motors_count))

            # Motor statuses
            motor_status_arrays_name = "g_" + dev_name.lower() + "_motor_statuses"
            fw_motor_status_arrays.append(
                "volatile StepMotorStatus {0}[{1}] = {{0}}; \\".format(motor_status_arrays_name, motors_count))

            # Device descriptors
            dev_motor_descr_list.append(dev_descriptor_name)
            fw_device_descriptors.append(
                "volatile StepMotorDevice {0} = {{ {{0}}, {{0}}, {4}, (volatile PStepMotorContext){6}, (volatile PStepMotorDevStatus){7}, {8}, {5}, (volatile StepMotorDescriptor**){3}, {2}, {1} }}; \\".format(
                    dev_descriptor_name,                #0
                    dev_id,                             #1
                    motors_count,                       #2
                    motor_descriptors_array_name,       #3
                    timer,                              #4
                    timer_irqn,                         #5
                    motor_context_arrays_name,          #6
                    dev_status_name,                    #7
                    dev_mstatus_size))                  #8

            sw_devices_descriptors.append(
                '{{ "{3}", {2}, {1}, {0} }}'.format(dev_id, motors_count, motor_descriptors_array_name, dev_name))

            fw_devices_array.append("(volatile PStepMotorDevice)&" + dev_descriptor_name)

            sw_config_name = "step_motor_{0}_config_ptr".format(dev_name)
            sw_config_declarations.append(f"extern const StepMotorConfig* {sw_config_name};")
            sw_configs.append(
                f"const StepMotorConfig* {sw_config_name} = {sw_config_array_name} + {indx};")

            indx += 1

        vocabulary = {"__NAMESPACE_NAME__": self.project_name,
                      "__STEP_MOTORS_BUFFERS__": concat_lines(fw_motor_buffers)[:-1],
                      "__STEP_MOTOR_MOTOR_DESCRIPTORS__": concat_lines(fw_motor_descriptors)[:-1],
                      "__STEP_MOTOR_DEVICE_DESCRIPTORS__": concat_lines(fw_device_descriptors)[:-1],
                      "__STEP_MOTOR_MOTOR_DESCRIPTORS_ARRAYS__": concat_lines(fw_motor_descriptor_arrays)[:-1],
                      "__STEP_MOTOR_MOTOR_CONTEXT_ARRAYS__": concat_lines(fw_motor_context_arrays)[:-1],
                      "__STEP_MOTOR_MOTOR_STATUS_ARRAYS__": concat_lines(fw_motor_status_arrays)[:-1],
                      "__STEP_MOTOR_DEVICES__": ", ".join(fw_devices_array),
                      "__STEP_MOTOR_DEVICE_COUNT__": len(fw_devices_array),
                      "__STEP_MOTOR_FW_TIMER_IRQ_HANDLERS__": concat_lines(timer_irq_handler_list)[:-1],
                      "__STEP_MOTORS_MOTOR_COUNTS__": concat_lines(fw_motor_dev_counts),
                      "__STEP_MOTORS_DEV_STATUSES__": concat_lines(fw_dev_status_buffers)[:-1],
                      "__SW_STEP_MOTOR_DESCRIPTORS__": concat_lines(sw_motor_descriptors),
                      "__SW_STEP_MOTOR_MOTOR_DESCRIPTOR_ARRAYS__": concat_lines(sw_motor_descriptor_arrays),
                      "__SW_STEP_MOTOR_DEVICE_DESCRIPTORS__": ", ".join(sw_devices_descriptors),
                      "__STEP_MOTOR_CONFIGURATION_DECLARATIONS__": concat_lines(sw_config_declarations),
                      "__STEP_MOTOR_CONFIGURATIONS__": concat_lines(sw_configs),
                      "__STEP_MOTOR_CONFIGURATION_ARRAY_NAME__": sw_config_array_name
                      }

        self.patch_templates(vocabulary)

        return

    def get_driver_gpio(self, mname: str, mcfg: dict, dev_name: str, dev_requires: dict) -> tuple:
        if "step" not in mcfg:
            raise RuntimeError(
                "step pin is not specified in device {0} for the motor definition for {1}".format(dev_name, mname))

        step_pin = self.get_gpio_with_default(mcfg.get("step"))
        dir_pin = self.get_gpio_with_default(mcfg.get("dir"))
        ms1_pin = self.get_gpio_with_default(mcfg.get("m1"))
        ms2_pin = self.get_gpio_with_default(mcfg.get("m2"))
        ms3_pin = self.get_gpio_with_default(mcfg.get("m3"))
        enable_pin = self.get_gpio_with_default(mcfg.get("enable"))
        reset_pin = self.get_gpio_with_default(mcfg.get("reset"))
        sleep_pin = self.get_gpio_with_default(mcfg.get("sleep"))
        fault_pin = self.get_gpio_with_default(mcfg.get("fault"))
        cw_endstop_pin = self.get_gpio_with_default(mcfg.get("cw_endstop"))
        ccw_endstop_pin = self.get_gpio_with_default(mcfg.get("ccw_endstop"))

        dev_requires[mname + "_step_gpio"] = {"gpio": step_pin}
        if dir_pin is not None:
            dev_requires[mname + "_dir_gpio"] = {"gpio": dir_pin}

        if ms1_pin is not None:
            dev_requires[mname + "_ms1_gpio"] = {"gpio": ms1_pin}

        if ms2_pin is not None:
            dev_requires[mname + "_ms2_gpio"] = {"gpio": ms2_pin}

        if ms3_pin is not None:
            dev_requires[mname + "_ms3_gpio"] = {"gpio": ms3_pin}

        if enable_pin is not None:
            dev_requires[mname + "_enable_gpio"] = {"gpio": enable_pin}

        if reset_pin is not None:
            dev_requires[mname + "_reset_gpio"] = {"gpio": reset_pin}

        if sleep_pin is not None:
            dev_requires[mname + "_sleep_gpio"] = {"gpio": sleep_pin}

        if fault_pin is not None:
            dev_requires[mname + "_fault_gpio"] = {"gpio": fault_pin}

        if cw_endstop_pin is not None:
            dev_requires[mname + "_cw_endstop_gpio"] = {"gpio": cw_endstop_pin}

        if ccw_endstop_pin is not None:
            dev_requires[mname + "_ccw_endstop_gpio"] = {"gpio": ccw_endstop_pin}

        return (
        step_pin, dir_pin, ms1_pin, ms2_pin, ms3_pin, enable_pin, reset_pin, sleep_pin, fault_pin, cw_endstop_pin,
        ccw_endstop_pin)

    def get_motor_description(self, for_firmware: bool, used_pins: tuple, mname: str, mcfg: dict, dev_name: str,
                              dev_requires: dict, buf_name: str, buf_size: int, default_speed: int, driver_type: str) -> str:
        step_pin, dir_pin, m1_pin, m2_pin, m3_pin, enable_pin, reset_pin, sleep_pin, fault_pin, cw_endstop_pin, ccw_endstop_pin = used_pins
        config_flags = []
        indention = self.tab
        drive_type_dict = {"unknown" : "STEP_MOTOR_DRIVER_UNKNOWN",
                           "a4998"   : "STEP_MOTOR_DRIVER_A4998",
                           "drv8825" : "STEP_MOTOR_DRIVER_DRV8825"}
        template = """ \\
{__config_flags__},\\
{__buffer_size__},\\
{__default_speed__},\\
{__motor_driver__},\\
{__cw_sft_limit__},\\
{__ccw_sft_limit__},\\"""

        fw_template = """
{__buffer__},\\
{{ {{ {__step_port__}, {__step_pin__} }},\\
  {{ {__dir_port__}, {__dir_pin__} }},\\
  {{ {__m1_port__}, {__m1_pin__} }},\\
  {{ {__m2_port__}, {__m2_pin__} }},\\
  {{ {__m3_port__}, {__m3_pin__} }},\\
  {{ {__enable_port__}, {__enable_pin__} }},\\
  {{ {__reset_port__}, {__reset_pin__} }},\\
  {{ {__sleep_port__}, {__sleep_pin__} }},\\
  {{ {__fault_port__}, {__fault_pin__} }},\\
  {{ {__cw_endstop_port__}, {__cw_endstop_pin__} }},\\
  {{ {__ccw_endstop_port__}, {__ccw_endstop_pin__} }} }},\\
{__fault_exticr__},\\
{__cw_endstop_exticr__},\\
{__ccw_endstop_exticr__}"""

        sw_template = """
{__motor_name__},\\
{__steps_per_revolution__}"""

        template += fw_template if for_firmware else sw_template
        steps_per_revolution = int(
            self.get_config_option(None, "steps_per_revolution", mname, mcfg, dev_name, None, None))

        vocabulary = {"__step_port__": indention + self.mcu_hw.GPIO_to_port(step_pin),
                      "__step_pin__": indention + str(self.mcu_hw.GPIO_to_pin_number(step_pin)),
                      "__default_speed__": indention + str(default_speed),
                      "__motor_driver__" : indention + drive_type_dict[driver_type],
                      "__motor_name__": indention + '"' + mname + '"',
                      "__steps_per_revolution__": indention + str(steps_per_revolution)}

        # ------------------------------- DIRECTION PIN -------------------------------
        if dir_pin is not None:
            vocabulary["__dir_port__"] = indention + self.mcu_hw.GPIO_to_port(dir_pin)
            vocabulary["__dir_pin__"] = indention + str(self.mcu_hw.GPIO_to_pin_number(dir_pin))
            config_flags.append(indention + "STEP_MOTOR_DIR_IN_USE |\\")
        else:
            vocabulary["__dir_port__"] = indention + "0"
            vocabulary["__dir_pin__"] = indention + "0"

        dv = self.get_config_option("dir", "default", mname, mcfg, dev_name, None, {"CW", "CCW"})
        if dv == "CW":
            config_flags.append(indention + "STEP_MOTOR_DIRECTION_CW |\\")

        # ------------------------------- M1 PIN -------------------------------
        if m1_pin is not None:
            vocabulary["__m1_port__"] = indention + self.mcu_hw.GPIO_to_port(m1_pin)
            vocabulary["__m1_pin__"] = indention + str(self.mcu_hw.GPIO_to_pin_number(m1_pin))
            config_flags.append(indention + "STEP_MOTOR_M1_IN_USE |\\")
        else:
            vocabulary["__m1_port__"] = indention + "0"
            vocabulary["__m1_pin__"] = indention + "0"

        dv = self.get_config_option("m1", "default", mname, mcfg, dev_name, None, {1, 0})
        if dv == 1:
            config_flags.append(indention + "STEP_MOTOR_M1_DEFAULT |\\")

        # ------------------------------- M2 PIN -------------------------------
        if m2_pin is not None:
            vocabulary["__m2_port__"] = indention + self.mcu_hw.GPIO_to_port(m2_pin)
            vocabulary["__m2_pin__"] = indention + str(self.mcu_hw.GPIO_to_pin_number(m2_pin))
            config_flags.append(indention + "STEP_MOTOR_M2_IN_USE |\\")
        else:
            vocabulary["__m2_port__"] = indention + "0"
            vocabulary["__m2_pin__"] = indention + "0"

        dv = self.get_config_option("m2", "default", mname, mcfg, dev_name, None, {1, 0})
        if dv == 1:
            config_flags.append(indention + "STEP_MOTOR_M2_DEFAULT |\\")

        # ------------------------------- M3 PIN -------------------------------
        if m3_pin is not None:
            vocabulary["__m3_port__"] = indention + self.mcu_hw.GPIO_to_port(m3_pin)
            vocabulary["__m3_pin__"] = indention + str(self.mcu_hw.GPIO_to_pin_number(m3_pin))
            config_flags.append(indention + "STEP_MOTOR_M3_IN_USE |\\")
        else:
            vocabulary["__m3_port__"] = indention + "0"
            vocabulary["__m3_pin__"] = indention + "0"

        dv = self.get_config_option("m3", "default", mname, mcfg, dev_name, None, {1, 0})
        if dv == 1:
            config_flags.append(indention + "STEP_MOTOR_M3_DEFAULT |\\")

        # ------------------------------- ENABLE PIN -------------------------------
        if enable_pin is not None:
            vocabulary["__enable_port__"] = indention + self.mcu_hw.GPIO_to_port(enable_pin)
            vocabulary["__enable_pin__"] = indention + str(self.mcu_hw.GPIO_to_pin_number(enable_pin))
            config_flags.append(indention + "STEP_MOTOR_ENABLE_IN_USE |\\")
        else:
            vocabulary["__enable_port__"] = indention + "0"
            vocabulary["__enable_pin__"] = indention + "0"

        dv = self.get_config_option("enable", "default", mname, mcfg, dev_name, None, {"enable", "disable"})
        if dv == "disable":
            config_flags.append(indention + "STEP_MOTOR_DISABLE_DEFAULT |\\")

        # ------------------------------- RESET PIN -------------------------------
        if reset_pin is not None:
            vocabulary["__reset_port__"] = indention + self.mcu_hw.GPIO_to_port(reset_pin)
            vocabulary["__reset_pin__"] = indention + str(self.mcu_hw.GPIO_to_pin_number(reset_pin))
            config_flags.append(indention + "STEP_MOTOR_RESET_IN_USE |\\")
        else:
            vocabulary["__reset_port__"] = indention + "0"
            vocabulary["__reset_pin__"] = indention + "0"

        # ------------------------------- SLEEP PIN -------------------------------
        if sleep_pin is not None:
            vocabulary["__sleep_port__"] = indention + self.mcu_hw.GPIO_to_port(sleep_pin)
            vocabulary["__sleep_pin__"] = indention + str(self.mcu_hw.GPIO_to_pin_number(sleep_pin))
            config_flags.append(indention + "STEP_MOTOR_SLEEP_IN_USE |\\")
        else:
            vocabulary["__sleep_port__"] = indention + "0"
            vocabulary["__sleep_pin__"] = indention + "0"

        dv = self.get_config_option("sleep", "default", mname, mcfg, dev_name, None, {"sleep", "wakeup"})
        if dv == "wakeup":
            config_flags.append(indention + "STEP_MOTOR_WAKEUP_DEFAULT |\\")

        # ------------------------------- ERROR CONFIGURATION -------------------------------
        dv = self.get_config_option(None, "error_action", mname, mcfg, dev_name, None, {"stop", "stop_all"})
        if dv == "stop_all":
            config_flags.append(indention + "STEP_MOTOR_CONFIG_ERROR_ALL |\\")

        # ------------------------------- FAULT PIN -------------------------------
        if fault_pin is not None:
            vocabulary["__fault_port__"] = indention + self.mcu_hw.GPIO_to_port(fault_pin)
            vocabulary["__fault_pin__"] = indention + str(self.mcu_hw.GPIO_to_pin_number(fault_pin))
            vocabulary["__fault_exticr__"] = indention + self.mcu_hw.GPIO_to_AFIO_EXTICR(fault_pin)
            dev_requires["{0}_{1}_fault_extiline".format(dev_name.lower(), mname.lower())] = {
                "exti_line": self.mcu_hw.GPIO_to_EXTI_line(fault_pin)}
            active_level = self.get_config_option("fault", "active_level", mname, mcfg, dev_name, None, {"high", "low"})
            if active_level == "high":
                config_flags.append(indention + "STEP_MOTOR_FAULT_ACTIVE_HIGH |\\")
            config_flags.append(indention + "STEP_MOTOR_FAULT_IN_USE |\\")

            dv = self.get_config_option("fault", "action", mname, mcfg, dev_name, None, {"ignore", "stop", "stop_all"})
            if dv != "stop":
                config_flags.append(indention + self.get_action_flag("STEP_MOTOR_CONFIG_FAILURE", dv) + " |\\")
        else:
            vocabulary["__fault_port__"] = indention + "0"
            vocabulary["__fault_pin__"] = indention + "0"
            vocabulary["__fault_exticr__"] = indention + "0"

        dv = self.get_config_option("sleep", "default", mname, mcfg, dev_name, None, {"sleep", "wakeup"})
        if dv == "wakeup":
            config_flags.append(indention + "STEP_MOTOR_WAKEUP_DEFAULT |\\")

        # ------------------------------- CW ENCODER PIN -------------------------------
        if cw_endstop_pin is not None:
            vocabulary["__cw_sft_limit__"] = indention + "0"
            vocabulary["__cw_endstop_port__"] = indention + self.mcu_hw.GPIO_to_port(cw_endstop_pin)
            vocabulary["__cw_endstop_pin__"] = indention + str(self.mcu_hw.GPIO_to_pin_number(cw_endstop_pin))
            vocabulary["__cw_endstop_exticr__"] = indention + self.mcu_hw.GPIO_to_AFIO_EXTICR(cw_endstop_pin)
            dev_requires["{0}_{1}_cw_endstop_extiline".format(dev_name.lower(), mname.lower())] = {
                "exti_line": self.mcu_hw.GPIO_to_EXTI_line(cw_endstop_pin)}
            active_level = self.get_config_option("cw_endstop", "active_level", mname, mcfg, dev_name, None,
                                                  {"high", "low"})
            if active_level == "high":
                config_flags.append(indention + "STEP_MOTOR_CWENDSTOP_ACTIVE_HIGH |\\")
            config_flags.append(indention + "STEP_MOTOR_CWENDSTOP_IN_USE |\\")
        else:
            vocabulary["__cw_endstop_port__"] = indention + "0"
            vocabulary["__cw_endstop_pin__"] = indention + "0"
            vocabulary["__cw_endstop_exticr__"] = indention + "0"
            cw_sft_limit = self.get_int_config_option("cw_endstop", "position_limit", mname, mcfg, dev_name, None)
            vocabulary["__cw_sft_limit__"] = indention + str(cw_sft_limit)

        dv = self.get_config_option("cw_endstop", "action", mname, mcfg, dev_name, None, {"ignore", "stop", "stop_all"})
        if dv != "stop":
            config_flags.append(indention + self.get_action_flag("STEP_MOTOR_CONFIG_CW_ENDSTOP", dv) + " |\\")

        # ------------------------------- CCW ENCODER PIN -------------------------------
        if ccw_endstop_pin is not None:
            vocabulary["__ccw_sft_limit__"] = indention + "0"
            vocabulary["__ccw_endstop_port__"] = indention + self.mcu_hw.GPIO_to_port(ccw_endstop_pin)
            vocabulary["__ccw_endstop_pin__"] = indention + str(self.mcu_hw.GPIO_to_pin_number(ccw_endstop_pin))
            vocabulary["__ccw_endstop_exticr__"] = indention + self.mcu_hw.GPIO_to_AFIO_EXTICR(ccw_endstop_pin)
            dev_requires["{0}_{1}_ccw_endstop_extiline".format(dev_name.lower(), mname.lower())] = {
                "exti_line": self.mcu_hw.GPIO_to_EXTI_line(ccw_endstop_pin)}
            active_level = self.get_config_option("ccw_endstop", "active_level", mname, mcfg, dev_name, None,
                                                  {"high", "low"})
            if active_level == "high":
                config_flags.append(indention + "STEP_MOTOR_CCWENDSTOP_ACTIVE_HIGH |\\")
            config_flags.append(indention + "STEP_MOTOR_CCWENDSTOP_IN_USE |\\")

        else:
            vocabulary["__ccw_endstop_port__"] = indention + "0"
            vocabulary["__ccw_endstop_pin__"] = indention + "0"
            vocabulary["__ccw_endstop_exticr__"] = indention + "0"
            ccw_sft_limit = self.get_int_config_option("ccw_endstop", "position_limit", mname, mcfg, dev_name, None)
            vocabulary["__ccw_sft_limit__"] = indention + str(ccw_sft_limit)

        dv = self.get_config_option("ccw_endstop", "action", mname, mcfg, dev_name, None, {"ignore", "stop", "stop_all"})
        if dv != "stop":
            config_flags.append(indention + self.get_action_flag("STEP_MOTOR_CONFIG_CCW_ENDSTOP", dv) + " |\\")

        # ------------------------------- Check software endstops are correct -------------------------------
        if cw_endstop_pin is None and ccw_endstop_pin is None and cw_sft_limit <= ccw_sft_limit:
            raise RuntimeError("Device {0} motor {1} : Software limit for CW direction must be greater than software limit for CCW direction".format(dev_name, mname));

        if len(config_flags) == 0:
            config_flags.append(indention + "0|\\")

        vocabulary["__config_flags__"] = concat_lines(config_flags)[:-2]
        vocabulary["__buffer__"] = indention + buf_name
        vocabulary["__buffer_size__"] = indention + str(buf_size)

        return template.format(**vocabulary)

    def get_action_flag(self, purpose, action : str):
        action_map = {"ignore": "_IGNORE", "stop_all": "_ALL"}
        return purpose+action_map[action]

    def get_int_config_option(self, line, opt: str, mname: str, mcfg: dict, dev_name: str, default)-> int:
        co = self.get_config_option(line,opt, mname, mcfg, dev_name, None, None)
        try:
            res = int(co)
        except ValueError:
            raise RuntimeError("Device '{0}' motor '{1}' line '{2}' has value '{3}' of not integer type.".format(dev_name, mname, line, opt))

        return res

    def get_config_option(self, line, opt: str, mname: str, mcfg: dict, dev_name: str, default,
                          allowed_values) -> str:
        if line is not None:
            if line not in mcfg:
                raise RuntimeError("Line {2} is not defined for motor {0} in device {1}".format(mname, dev_name, line))
            linecfg = mcfg[line]
        else:
            linecfg = mcfg

        if opt in linecfg:
            val = linecfg[opt]
        else:
            val = default

        if val is None:
            # This option must be specified, it's not optional
            raise RuntimeError(
                "Option {0} is mandatory, but it is not specified for the motor {1} in device {2}".format(opt, mname,
                                                                                dev_name))
        elif allowed_values is not None:
            if val in allowed_values:
                return val
            else:
                raise RuntimeError(
                    "Invalid {0} value specified for the motor {1} in device {2}".format(opt, mname, dev_name))
        else:
            return val

    def get_drive_type(self, mname: str, mcfg: dict, dev_name: str):
        dt = self.get_config_option(None, "drive_type", mname, mcfg, dev_name, "unknown",
                                    {"unknown", "a4998", "drv8825"})

        # calculate default microstep value
        if "m1" in mcfg:
            m1 = self.get_config_option("m1", "default", mname, mcfg, dev_name, None, {1, 0})
        else:
            m1 = 0

        if "m2" in mcfg:
            m2 = self.get_config_option("m2", "default", mname, mcfg, dev_name, None, {1, 0})
        else:
            m2 = 0

        if "m3" in mcfg:
            m3 = self.get_config_option("m3", "default", mname, mcfg, dev_name, None, {1, 0})
        else:
            m3 = 0

        microstep = m1 + (m2<<1) + (m3<<2)
        bad_ms_values = set()

        # sanitize fault pin (is not available in a4998)
        if dt == "a4998":
            bad_ms_values.update({4,5,6})
            if "fault" in mcfg:
                raise RuntimeError(
                    "Motor {0} in device {1} uses fault pin. However A4998 drivers don't it.".format(mname, dev_name))

        # check for incorrect default microstep values
        if microstep in bad_ms_values:
            raise RuntimeError("Motor {0} (drive type is: {2}) in device {1} uses unacceptable default value for microsteps(M1={3}, M2={4}, M3={5})".format(mname, dev_name, dt, m1, m2, m3))

        if dt == "unknown":
            return None
        else:
            return dt


#!/usr/bin/python
# -*- coding: utf-8 -*-
__author__ = 'hina'

# 传说中的ORM技术：Object-Relational Mapping，把关系数据库的表结构映射到对象上

# 在Python中，最有名的ORM框架是SQLAlchemy

from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = "user"

    id = Column(String(20), primary_key = True)
    name = Column(String(20))

engine = create_engine("mysql+mysqlconnector://root:57235742@localhost:3306/test")
DBSession = sessionmaker(bind=engine)

session = DBSession()
new_user = User(id = "5", name = "Bob")
session.add(new_user)
session.commit()
session.close()

session = DBSession()
user = session.query(User).filter(User.id == "5").one()
print("type", type(user))
print("name", user.name)
session.close()


from parser import Parser

class Summarizer:
    def __init__(self):
        self.parser = Parser()

    def summarize(self, text):
        sentences = self.parser.splitSentences(text)
        #print(sentences)
        (keywords, wordCount) = self.parser.getKeywords(text)
        topKeywords = self.getTopKeywords(keywords[:10], wordCount)

        tagged = self.parser.getTagsForWords(text)
        print(tagged)
        NP = self.parser.getNounPositions('NP', tagged, text)
        print(NP)
        PRP = self.parser.getProNounPositions(tagged, text)
        print(PRP)
        text = self.parser.pronounReplaceWithNearNoun(text, PRP, NP)
        sentences = self.parser.splitSentences(text)
        print(sentences)

        result = self.computeScore(sentences, topKeywords)
        result = self.sortScore(result)

        return result

    def getTopKeywords(self, keywords, wordCount):
        # Add getting top keywords in the database here
        for keyword in keywords:
            articleScore = 1.0 * keyword['count'] / wordCount
            keyword['totalScore'] = articleScore * 1.5

        return keywords

    def sortScore(self, dictList):
        return sorted(dictList, key=lambda x: -x['totalScore'])

    def sortSentences(self, dictList):

        return sorted(dictList, key=lambda x: x['order'])

    def computeScore(self, sentences, topKeywords):
        keywordList = [keyword['word'] for keyword in topKeywords]
        summaries = []

        for i, sentence in enumerate(sentences):
            sent = self.parser.removePunctations(sentence)
            words = self.parser.splitWords(sent)

            sbsFeature = self.sbs(words, keywordList)
            dbsFeature = self.dbs(words, topKeywords, keywordList)

            sentenceLength = self.parser.getSentenceLengthScore(words)
            sentencePosition = self.parser.getSentencePositionScore(i, len(sentences))
            keywordFrequency = (sbsFeature + dbsFeature) / 2.0 * 10.0
            totalScore = (0.5 + keywordFrequency * 2.0 + sentenceLength * 0.5 + sentencePosition * 1.0) / 4.0

            summaries.append({
                'totalScore': totalScore,
                'sentence': sentence,
                'order': i
            })

        return summaries

    def sbs(self, words, keywordList):
        score = 0.0
        if len(words) == 0:
            return 0
        for word in keywordList:
            if word in words:
                score += 1
        return score / len(keywordList)

    def dbs(self, words, topKeywords, keywordList):
        k = len(list(set(words) & set(keywordList))) + 1
        summ = 0.0
        firstWord = {}
        secondWord = {}

        for i, word in enumerate(words):
            if word in keywordList:
                index = keywordList.index(word)

                if firstWord == {}:
                    firstWord = {'i': i, 'score': topKeywords[index]['totalScore']}
                else:
                    secondWord = firstWord
                    firstWord = {'i': i, 'score': topKeywords[index]['totalScore']}
                    distance = firstWord['i'] - secondWord['i']

                    summ += (firstWord['score'] * secondWord['score']) / (distance ** 2)

        return (1.0 / k * (k + 1.0)) * summ


from airflow.hooks.postgres_hook import PostgresHook
from airflow.models import BaseOperator
from airflow.utils.decorators import apply_defaults

class DropTableOperator(BaseOperator):

    ui_color = '#076D9F'
    template_fields = ('tables', )

    @apply_defaults
    def __init__(self,
                 schema,
                 tables,
                 redshift_conn_id='redshift',
                 *args,
                 **kwargs):

        super(DropTableOperator, self).__init__(*args, **kwargs)
        self.schema = schema
        self.tables = tables
        self.redshift_conn_id = redshift_conn_id

    def execute(self, context):
        self.redshift_hook = PostgresHook(self.redshift_conn_id)

        for table in self.tables:
            self.log.info(f'Dropping table: {self.schema}.{table}')
            self.redshift_hook.run(
                f'DROP TABLE IF EXISTS {self.schema}.{table}'
            )


from requests import Session, Response

# Shamelessly stolen from: https://stackoverflow.com/a/6798042/11985743
class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class SdarotController(Session, metaclass=Singleton):
    """
    Maybe in future, using a singleton is better since
    it will use only 1 request for the entire session.
    """

    def __init__(self, sdarot_base: str = None) -> None:
        super().__init__()

        # The first time we are called, we must get the Sdarot base URL
        # If we call this later, the singleton metaclass will catch it.
        # Therefore, if we get 'None' now as the parameter, there is an issue.
        if not sdarot_base:
            raise Exception(
                "No Sdarot URL found, make sure you have made an instance of the PySdarot class at least once. "
                "If you have and are still facing this issue, then please report this as a bug."
            )

        # Singletons don't need static classes, we can write this directly to the property
        self.__sdarot_base = sdarot_base

        # Initialize the session with fake UA
        self.headers.update({
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/83.0.4103.97 Safari/537.36',
            'origin': self.__sdarot_base,
            'referer': self.__sdarot_base
        })

        # Get initial 'anon'/guest cookies
        self.get(self.__sdarot_base)

        # Add base URL to relative paths
        self.request = self.request_override

    def request_override(self, method: str, relative_url: str, full_url: bool = False, **kwargs) -> Response:
        # Don't modify URL
        if full_url:
            return super().request(method, relative_url, **kwargs)
        else:
            # Attach relative URL to base
            # Pretty weird practice, but it's annoying to pass the base URL around using parameters
            # If someone has a better suggestion, feel free to drop a PR! :)
            return super().request(
                method=method,
                url=self.__sdarot_base + relative_url,
                **kwargs
            )


from sys import stdin

def parseints(line):
    return map(int, line.split())

line = stdin.readline().strip()

while line != '0':
    k, m = list(parseints(line))
    chosen = set(parseints(stdin.readline()))

    reqs = True
    for _ in range(m):
        c, r, *courses = list(parseints(stdin.readline()))

        if len(chosen.intersection(set(courses))) < r:
            reqs = False

    print('yes' if reqs else 'no')

    line = stdin.readline().strip()


import pygame
import random
from pygame.locals import *

WIDTH = 1400
HEIGHT = 800
class gameover:
    flag = 0
class Bullet:
    bullet_list = []
    # 炮弹发射延迟
    interval = 0
    def __init__(self, pea):
        self.image = pygame.image.load('images/bullet.png')
        self.image_rect = self.image.get_rect()
        self.image_rect.centery = pea.image_rect.centery - 90
        self.image_rect.left = pea.image_rect.right - 50
    # 炮弹显示
    def display(self):
        screen.blit(self.image, self.image_rect)
    # 炮弹移动
    def move(self):
        self.image_rect.move_ip(6, 0)
        # 如果炮弹越界就删除
        if self.image_rect.left > WIDTH:
            Bullet.bullet_list.remove(self)
class Bullet1:
    bullet_list = []
    # 炮弹发射延迟
    interval = 0
    def __init__(self, pea):
        self.image = pygame.image.load('images/bullet1.png')
        self.image_rect = self.image.get_rect()
        self.image_rect.centery = pea.image_rect.centery - 90
        self.image_rect.left = pea.image_rect.right - 50
    # 炮弹显示
    def display(self):
        screen.blit(self.image, self.image_rect)
    # 炮弹移动
    def move(self):
        self.image_rect.move_ip(10, 0)
        # 如果炮弹越界就删除
        if self.image_rect.left > WIDTH:
            Bullet1.bullet_list.remove(self)
class Prop:
    interval = 0
    prop_list = []

    def __init__(self):
        self.image = pygame.image.load('images/prop.png')
        self.image_rect = self.image.get_rect()
        self.image_rect.centery = random.randint(350, 700)
        self.image_rect.centerx = random.randint(400, 760)
        self.image = pygame.transform.scale(self.image, (50, 80))

    def display(self):
        screen.blit(self.image, self.image_rect)
        if self.image_rect.colliderect(peas.image_rect):
            Prop.prop_list.remove(self)
            peas.cishu+=1

class peas:
    cishu = 0

    def __init__(self):
        self.image = pygame.image.load('images/daifu.png')
        self.image_rect = self.image.get_rect()
        self.image = pygame.transform.scale(self.image, (80, 150))
        self.image_rect.centery = 400
        self.image_rect.centerx = 400
        # 定义移动状态
        self.moveup = False
        self.movedown = False
        self.moveleft = False
        self.moveright = False
        self.shoot = False

    def move_up(self):
        self.image_rect.move_ip(0, -5)
        for z in Zombie.zombie_list:
            if self.image_rect.colliderect(z.image_rect):
                gameover.flag = 1
        for z1 in Zombie1.zombie1_list:
            if self.image_rect.colliderect(z1.image_rect):
                gameover.flag = 1
# 这里新添了代码
        for z2 in Zombie2.zombie2_list:
                    if self.image_rect.colliderect(z2.image_rect):
                        gameover.flag = 1

    def move_down(self):
        self.image_rect.move_ip(0, 5)
        for z in Zombie.zombie_list:
            if self.image_rect.colliderect(z.image_rect):
                gameover.flag = 1
        for z1 in Zombie1.zombie1_list:
            if self.image_rect.colliderect(z1.image_rect):
                gameover.flag = 1

# 这里新添了代码
        for z2 in Zombie2.zombie2_list:
            if self.image_rect.colliderect(z2.image_rect):
                gameover.flag = 1

    def move_left(self):
        self.image_rect.move_ip(-5, 0)
        for z in Zombie.zombie_list:
            if self.image_rect.colliderect(z.image_rect):
                gameover.flag = 1
        for z1 in Zombie1.zombie1_list:
            if self.image_rect.colliderect(z1.image_rect):
                gameover.flag = 1

# 这里新添了代码
        for z2 in Zombie2.zombie2_list:
            if self.image_rect.colliderect(z2.image_rect):
                gameover.flag = 1

    def move_right(self):
        self.image_rect.move_ip(5, 0)
        for z in Zombie.zombie_list:
            if self.image_rect.colliderect(z.image_rect):
                gameover.flag = 1
        for z1 in Zombie1.zombie1_list:
            if self.image_rect.colliderect(z1.image_rect):
                gameover.flag = 1

# 这里新添了代码
        for z2 in Zombie2.zombie2_list:
            if self.image_rect.colliderect(z2.image_rect):
                gameover.flag = 1

    def display(self):
        screen.blit(self.image, self.image_rect)

    def shoot_bullet(self):
        # 创建炮弹
        bullet = Bullet(self)
        bullet.bullet_list.append(bullet)

    def shoot_bullet1(self):
        # 创建炮弹
        bullet1 = Bullet1(self)
        bullet1.bullet_list.append(bullet1)

class Zombie:
    score = 15
    # 创建频率
    interval = 0
    # 保存多个僵尸
    zombie_list = []

    def __init__(self):
        self.image = pygame.image.load('images/zombie.gif')
        self.image_rect = self.image.get_rect()
        self.image_rect.centery = random.randint(300, 700)
        self.image_rect.centerx = 1300
        self.count = 0

    def display(self):
        screen.blit(self.image, self.image_rect)

    def move(self):
        self.image_rect.move_ip(-1, 0)
        # 如果僵尸越界就删除
        if self.image_rect.left < 200:
            Zombie.zombie_list.remove(self)
        # 三颗子弹打死一只小僵尸
        for b in Bullet.bullet_list:
            if self.image_rect.colliderect(b.image_rect):
                self.count = self.count + 1
                if self.count == 4:
                    Zombie.zombie_list.remove(self)
                    Bullet.bullet_list.remove(b)
                    self.count = 0
                    Zombie.score += 5
                else:
                    Bullet.bullet_list.remove(b)
        for b in Bullet1.bullet_list:
            if self.image_rect.colliderect(b.image_rect):
                Zombie.zombie_list.remove(self)
                Zombie.score += 5

        if self.image_rect.colliderect(peas.image_rect):
            gameover.flag = 1

class Zombie1:
    # 创建频率
    score = 0
    interval = 0
    # 保存多个僵尸
    zombie1_list = []

    def __init__(self):
        self.image = pygame.image.load('images/zombie1.gif')
        self.image_rect = self.image.get_rect()

        self.image_rect.centery = random.randint(300, 700)
        self.image_rect.centerx = 1300
        self.count = 0

    def display(self):
        screen.blit(self.image, self.image_rect)

    def move(self):
        self.image_rect.move_ip(-1, 0)
        # 如果僵尸越界就删除
        if self.image_rect.left < 200:
            Zombie1.zombie1_list.remove(self)
        # 三颗子弹打死一只小僵尸
        for b in Bullet.bullet_list:
            if self.image_rect.colliderect(b.image_rect):
                self.count = self.count + 1

                if self.count == 6:
                    Zombie1.zombie1_list.remove(self)
                    Bullet.bullet_list.remove(b)
                    self.count = 0
                    Zombie1.score += 10
                else:
                    Bullet.bullet_list.remove(b)

        for b in Bullet1.bullet_list:
            if self.image_rect.colliderect(b.image_rect):
                Zombie1.zombie1_list.remove(self)

                Zombie1.score += 15
        if self.image_rect.colliderect(peas.image_rect):
            gameover.flag = 1

# 这里新添了代码

class Zombie2:
    # 创建频率
    score = 0
    interval = 0
    # 保存多个僵尸
    zombie2_list = []
    def __init__(self):
        self.image = pygame.image.load('images/zombie2.png')
        self.image_rect = self.image.get_rect()
        self.image = pygame.transform.scale(self.image, (150, 200))
        self.image_rect.centery = random.randint(400, 700)
        self.image_rect.centerx = 1300
        self.count = 0

    def display(self):
        screen.blit(self.image, self.image_rect)

    def move(self):
        self.image_rect.move_ip(-1, 0)
        # 如果僵尸越界就删除
        if self.image_rect.left < 200:
            Zombie2.zombie2_list.remove(self)
        # 三颗子弹打死一只小僵尸
        for b in Bullet.bullet_list:
            if self.image_rect.colliderect(b.image_rect):
                self.count = self.count + 1

                if self.count == 7:
                    Zombie2.zombie2_list.remove(self)
                    Bullet.bullet_list.remove(b)
                    self.count = 0
                    Zombie2.score += 15
                else:
                    Bullet.bullet_list.remove(b)

        for b in Bullet1.bullet_list:
            if self.image_rect.colliderect(b.image_rect):
                Zombie2.zombie2_list.remove(self)

                Zombie2.score += 15
        if self.image_rect.colliderect(peas.image_rect):
            gameover.flag = 1

def key_control():
    for event in pygame.event.get():
        # 事件类型
        if event.type == QUIT:
            pygame.quit()
            exit()
        # 判断键盘输入
        elif event.type == KEYDOWN:
            if event.key == (K_w or K_UP):
                peas.moveup = True
            elif event.key == (K_s or K_DOWN):
                peas.movedown = True
            elif event.key == (K_a or K_LEFT):
                peas.moveleft = True
            elif event.key == (K_d or K_RIGHT):
                peas.moveright = True
            elif event.key == K_SPACE:
                peas.shoot = True
            elif event.key == K_n and peas.cishu > 0:
                peas.shoot_bullet1()
                peas.cishu -= 1
        elif event.type == KEYUP:
            if event.key == (K_w or K_UP):
                peas.moveup = False
            elif event.key == (K_s or K_DOWN):
                peas.movedown = False
            elif event.key == (K_a or K_LEFT):
                peas.moveleft = False
            elif event.key == (K_d or K_RIGHT):
                peas.moveright = False
            elif event.key == K_SPACE:
                peas.shoot = False

if __name__ == '__main__':
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    background_image = pygame.image.load('images/beijing.png')
    background_image = pygame.transform.scale(background_image, (WIDTH, HEIGHT))
    # 创建时钟
    clock = pygame.time.Clock();
    # 创建一个对象
    peas = peas()

    while gameover.flag == 0:

        screen.fill((0, 0, 0))
        screen.blit(background_image, (0, 0))  # 背景显示
        peas.display()
        # 键盘输入
        key_control()
        # 移动判断
        if peas.moveup == True and peas.image_rect.top > 150:
            peas.move_up()
        if peas.movedown == True and peas.image_rect.bottom < 900:
            peas.move_down()
        if peas.moveleft == True and peas.image_rect.centerx > 350:
            peas.move_left()
        if peas.moveright == True and peas.image_rect.centerx < 960:
            peas.move_right()
        Bullet.interval += 1
        if peas.shoot == True and Bullet.interval >= 20 and Zombie.score + Zombie1.score + Zombie2.score > 0:
            peas.shoot_bullet()
            Bullet.interval = 0
            Zombie.score -= 1
        # 创建僵尸
        Zombie.interval += 1
        if Zombie.interval >= 250:
            Zombie.interval = 0
            zombie = Zombie()
            Zombie.zombie_list.append(zombie)
        Zombie1.interval += 1
        if Zombie1.interval >= 300:
            Zombie1.interval = 0
            zombie1 = Zombie1()
            Zombie1.zombie1_list.append(zombie1)

        Zombie2.interval += 1
        if Zombie2.interval >= 350:
            Zombie2.interval = 0
            zombie2 = Zombie2()
            Zombie2.zombie2_list.append(zombie2)
            Zombie2.interval += 1

        Prop.interval += 1
        if Prop.interval >= 800:

            prop = Prop()
            Prop.prop_list.append(prop)
            Prop.interval = 0

        # 显示所有炮弹
        for bullet in Bullet.bullet_list:
            # 炮弹显示
            bullet.display()
            # 炮弹移动
            bullet.move()
        for bullet in Bullet1.bullet_list:
            # 炮弹显示
            bullet.display()
            # 炮弹移动
            bullet.move()
        # 显示所有僵尸
        for zombie in Zombie.zombie_list:
            # 僵尸显示
            zombie.display()
            # 僵尸移动
            zombie.move()
        for zombie1 in Zombie1.zombie1_list:
            # 僵尸显示
            zombie1.display()
            # 僵尸移动
            zombie1.move()

        for zombie2 in Zombie2.zombie2_list:
            # 僵尸显示
            zombie2.display()
            # 僵尸移动
            zombie2.move()

        for prop in Prop.prop_list:
            prop.display()

        if Zombie.score + Zombie1.score + Zombie2.score  >=200:  # 分数到达200分就结束
            gameover.flag = 2
        clock.tick(60)

        pygame.font.init()
        # 金币显示
        myfont = pygame.font.Font(None, 50)
        textImage = myfont.render("Your coins:" + str(Zombie.score + Zombie1.score + Zombie2.score ), True, (255, 215, 0))
        screen.blit(textImage, (1150, 10))
        # 特殊金币显示
        myfont = pygame.font.Font(None, 50)
        textImage = myfont.render("Your NBcoins:" + str(peas.cishu), True, (255, 215, 0))
        screen.blit(textImage, (1110, 50))

        pygame.display.update()

    while gameover.flag == 1:
        screen = pygame.display.set_mode((WIDTH, HEIGHT))
        jieshuhuamian = pygame.image.load('images/youxijieshu.png')
        screen.blit(jieshuhuamian, (0, 0))
        key_control()
        pygame.display.update()
    while gameover.flag == 2:
        screen = pygame.display.set_mode((WIDTH, HEIGHT))
        jieshuhuamian = pygame.image.load('images/chuangguanchenggong.png')
        screen.blit(jieshuhuamian, (0, 0))
        key_control()
        pygame.display.update()


"""Import avro file into BigQuery."""

import os

from google.cloud import bigquery

def iot_transformed_data(data,context) :

    client = bigquery.Client()

    bucketname = data['bucket']

    timeCreated = data['timeCreated']

    dataset_id = "streaming_data_analysis"

    dataset_ref = client.dataset(dataset_id)

    job_config = bigquery.LoadJobConfig()

    job_config.write_disposition = bigquery.WriteDisposition.WRITE_TRUNCATE

    job_config.autodetect = True

    job_config.ignore_unknown_values = True

    job_config.source_format = bigquery.SourceFormat.AVRO

    uri = bucketname+"/iot_transformed_data/*.avro"

    load_job = client.load_table_from_uri(uri,dataset_ref.table('device_energy_consumption'),job_config=job_config)

    print("Starting Job {}".format(load_job.job_id))

    load_job.result()

    print("Job Finished")

    destination_table = client.get_table(dataset_ref.table('device_energy_consumption'))
    print('Loaded {} rows.' .format(destination_table.num_rows))


import utils

# Anzahl aller Knoten im Netzwerk
nodes_number = 256
# Anzahl der korrumpierten Knoten
corrupted_number = 200
# Anzahl der Cluster im Netzwerk
cluster_number = 2
# Anzahl der ausgewählten Nodes pro Cluster
picked_nodes_number = 8
# Anzahl der Iterationen für die Simulation
iteration_number = 100
# Anzahl der gleichen Ergebnisse im gesamten Quorum
threshold = 0.5
# Anzahl der gleichen Ergebnisse im Nested Quorum
nested_threshold = 0.5

debug = False

for v in [4, 8, 16, 32, 64]:

    for c in [1, 2, 4, 8, 16, 32, 64]:
        successful_corrupted_number = 0
        cluster_number = c
        picked_nodes_number = int(v / c)
        corrupted_number = picked_nodes_number

        if picked_nodes_number == 0:
            break

        for _ in range(iteration_number):
            # Create clusters
            clusters = utils.create_clusters(nodes_number, cluster_number)
            if debug:
                print('clusters:' + str(clusters))

            # Create corrupted nodes
            corrupted_clusters = utils.create_corrupted_clusters(clusters, corrupted_number)
            if debug:
                print('corrupted clusters:' + str(corrupted_clusters))

            successful_corrupted_clusters = utils.filter_corrupted_clusters(corrupted_clusters, picked_nodes_number, nested_threshold)
            if debug:
                print('successful corrupted clusters:' + str(successful_corrupted_clusters))

            successful_corrupted_cluster_number = len(successful_corrupted_clusters)
            successful_corrupted_ratio = successful_corrupted_cluster_number / cluster_number
            if successful_corrupted_ratio > threshold:
                successful_corrupted_number += 1

        print('V: ' + str(v))
        print('Cluster count: ' + str(cluster_number))
        print('Picked nodes count: ' + str(picked_nodes_number))
        print('Successful corrupted: ' + str(successful_corrupted_number))
        print('Successful corrupted ratio: ' + str(successful_corrupted_number / iteration_number))
        print('-'*100)


import numpy as np

from utils import gauss

class CVTarget:
    def __init__(self,
                 x: np.float,
                 y: np.float,
                 F: np.array,
                 H: np.array,
                 Q: np.array,
                 R: np.array,
                 g: np.float,
                 P_D: np.float,
                 lam: np.float):
        self.lam = lam
        self.x = np.array([
            [x],
            [y],
            [0],
            [0],
        ])
        self.F = F
        self.H = H
        self.Q = Q
        self.R = R
        self.P = np.eye(4, 4)
        self.S = self.innov_cov(self.H, self.P, self.R)
        self.g = g
        self.P_D = P_D

    @staticmethod
    def innov_cov(H, P, R):
        return H@P@np.transpose(H) + R

    def predict(self):
        self.x = self.F@self.x
        self.P = self.F@self.P@np.transpose(self.F) + self.Q
        self.S = self.innov_cov(self.H, self.P, self.R)

    def update(self, Z: list):
        self.S = self.innov_cov(self.H, self.P, self.R)
        zpred = self.zpred()
        innovations = []
        betas_unorm = []
        for z in Z:
            if z.size != 2:
                raise Exception("z has wrong dimension", z)
            innovations.append(z - zpred)
            betas_unorm.append(self.P_D * gauss(z, zpred, self.S))
        betas = betas_unorm / np.sum(betas_unorm)

        # Reduce the mixture to a single innovation weighted by betas
        ny = np.zeros_like(zpred)
        for j, assoc_ny in enumerate(innovations):
            ny += betas[j] * assoc_ny
        W = self.P@np.transpose(self.H)@np.linalg.inv(self.S)

        self.x = self.x + W@ny

        beta_boi = 0
        for j, assoc_ny in enumerate(innovations):
            beta_boi += betas[j]*assoc_ny@assoc_ny.T
        sprd_innov = W@(beta_boi - ny@ny.T)@W.T
        beta_0 = self.lam * (1 - self.P_D)

        self.P = self.P - (1 - beta_0)*W@self.S@W.T + sprd_innov

    def zpred(self):
        return self.H@self.x

    def gate(self, Z):
        zpred = self.zpred()  # declare this first for efficiency
        gated = np.array([z for z in Z if np.transpose(z - zpred)@np.linalg.inv(self.S)@(z - zpred) < self.g**2])
        return gated.reshape((gated.size // 2, 2, 1))


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import argparse
import collections
from easydict import EasyDict as edict
import logging
import numpy as np

from mindspore.mindrecord import FileWriter
import src.tokenization as tokenization

class SampleInstance():
    """A single sample instance (sentence pair)."""

    def __init__(self, source_sos_tokens, source_eos_tokens, target_sos_tokens, target_eos_tokens):
        self.source_sos_tokens = source_sos_tokens
        self.source_eos_tokens = source_eos_tokens
        self.target_sos_tokens = target_sos_tokens
        self.target_eos_tokens = target_eos_tokens

    def __str__(self):
        s = ""
        s += "source sos tokens: %s\n" % (" ".join(
            [tokenization.printable_text(x) for x in self.source_sos_tokens]))
        s += "source eos tokens: %s\n" % (" ".join(
            [tokenization.printable_text(x) for x in self.source_eos_tokens]))
        s += "target sos tokens: %s\n" % (" ".join(
            [tokenization.printable_text(x) for x in self.target_sos_tokens]))
        s += "target eos tokens: %s\n" % (" ".join(
            [tokenization.printable_text(x) for x in self.target_eos_tokens]))
        s += "\n"
        return s

    def __repr__(self):
        return self.__str__()

def write_instance_to_file(writer, instance, tokenizer, max_seq_length):
    """Create files from `SampleInstance`s."""

    def _convert_ids_and_mask(input_tokens):
        input_ids = tokenizer.convert_tokens_to_ids(input_tokens)
        input_mask = [1] * len(input_ids)
        assert len(input_ids) <= max_seq_length

        while len(input_ids) < max_seq_length:
            input_ids.append(0)
            input_mask.append(0)

        assert len(input_ids) == max_seq_length
        assert len(input_mask) == max_seq_length

        return input_ids, input_mask

    source_sos_ids, source_sos_mask = _convert_ids_and_mask(instance.source_sos_tokens)
    source_eos_ids, source_eos_mask = _convert_ids_and_mask(instance.source_eos_tokens)
    target_sos_ids, target_sos_mask = _convert_ids_and_mask(instance.target_sos_tokens)
    target_eos_ids, target_eos_mask = _convert_ids_and_mask(instance.target_eos_tokens)

    features = collections.OrderedDict()
    features["source_sos_ids"] = np.asarray(source_sos_ids,dtype=np.int32)
    features["source_sos_mask"] = np.asarray(source_sos_mask,dtype=np.int32)
    features["source_eos_ids"] = np.asarray(source_eos_ids,dtype=np.int32)
    features["source_eos_mask"] = np.asarray(source_eos_mask,dtype=np.int32)
    features["target_sos_ids"] = np.asarray(target_sos_ids,dtype=np.int32)
    features["target_sos_mask"] = np.asarray(target_sos_mask,dtype=np.int32)
    features["target_eos_ids"] = np.asarray(target_eos_ids,dtype=np.int32)
    features["target_eos_mask"] = np.asarray(target_eos_mask,dtype=np.int32)
    writer.write_raw_data([features])
    return features

def create_training_instance(source_words, target_words, max_seq_length):
    """Creates `SampleInstance`s for a single sentence pair."""
    EOS = "</s>"
    SOS = "<s>"

    source_sos_tokens = [SOS] + source_words
    source_eos_tokens = source_words + [EOS]
    target_sos_tokens = [SOS] + target_words
    target_eos_tokens = target_words + [EOS]

    instance = SampleInstance(
        source_sos_tokens=source_sos_tokens,
        source_eos_tokens=source_eos_tokens,
        target_sos_tokens=target_sos_tokens,
        target_eos_tokens=target_eos_tokens)
    return instance

cfg = edict({
        'input_file': './data/ch_en_all.txt',
        'vocab_file': './data/ch_en_vocab.txt',
        'train_file_mindrecord': './path_cmn/train.mindrecord',
        'eval_file_mindrecord': './path_cmn/test.mindrecord',
        'train_file_source': './path_cmn/source_train.txt',
        'eval_file_source': './path_cmn/source_test.txt',
        'num_splits':1,
        'clip_to_max_len': False,
        'max_seq_length': 40
})

def main(eval_idx):
    os.mkdir('path_cmn')
    tokenizer = tokenization.WhiteSpaceTokenizer(vocab_file=cfg.vocab_file)

    writer_train = FileWriter(cfg.train_file_mindrecord, cfg.num_splits)
    writer_eval = FileWriter(cfg.eval_file_mindrecord, cfg.num_splits)
    data_schema = {"source_sos_ids": {"type": "int32", "shape": [-1]},
                   "source_sos_mask": {"type": "int32", "shape": [-1]},
                   "source_eos_ids": {"type": "int32", "shape": [-1]},
                   "source_eos_mask": {"type": "int32", "shape": [-1]},
                   "target_sos_ids": {"type": "int32", "shape": [-1]},
                   "target_sos_mask": {"type": "int32", "shape": [-1]},
                   "target_eos_ids": {"type": "int32", "shape": [-1]},
                   "target_eos_mask": {"type": "int32", "shape": [-1]}
                   }

    writer_train.add_schema(data_schema, "tranformer train")
    writer_eval.add_schema(data_schema, "tranformer eval")

    index = 0
    f_train = open(cfg.train_file_source, 'w', encoding='utf-8')
    f_test = open(cfg.eval_file_source,'w',encoding='utf-8')
    f = open(cfg.input_file, "r", encoding='utf-8')
    for s_line in f:
        line = tokenization.convert_to_unicode(s_line)

        source_line, target_line = line.strip().split("\t")
        source_tokens = tokenizer.tokenize(source_line)
        target_tokens = tokenizer.tokenize(target_line)

        if len(source_tokens) >= (cfg.max_seq_length-1) or len(target_tokens) >= (cfg.max_seq_length-1):
            if cfg.clip_to_max_len:
                source_tokens = source_tokens[:cfg.max_seq_length-1]
                target_tokens = target_tokens[:cfg.max_seq_length-1]
            else:
                continue

        index = index + 1
        print(source_tokens)
        instance = create_training_instance(source_tokens, target_tokens, cfg.max_seq_length)

        if index in eval_idx:
            f_test.write(s_line)
            features = write_instance_to_file(writer_eval, instance, tokenizer, cfg.max_seq_length)
        else:
            f_train.write(s_line)
            features = write_instance_to_file(writer_train, instance, tokenizer, cfg.max_seq_length)
    f.close()
    f_test.close()
    f_train.close()
    writer_train.commit()
    writer_eval.commit()

if __name__ == "__main__":
    sample_num = 23607
    eval_idx = np.random.choice(sample_num, int(sample_num*0.2), replace=False)
    parser = argparse.ArgumentParser(description='Transformer creating dataset')
    parser.add_argument('--data_url', required=True, default=None, help='Location of data.')
    parser.add_argument('--train_url', required=True, default=None, help='Location of training outputs.')
    args_opt = parser.parse_args()

    import moxing as mox
    mox.file.copy_parallel(src_url=args_opt.data_url, dst_url='./data/')

    main(eval_idx)
    mox.file.copy_parallel(src_url='./path_cmn/', dst_url=args_opt.train_url)


from PyQt5.QtWidgets import QDialog, QLabel, QLineEdit, QComboBox, QPushButton, QFormLayout, QMessageBox, QPlainTextEdit

class InputDialogWindow(QDialog):
    # def __init__(self, windowTitle, parent = None):
    #     super(inputdialogdemo, self).__init__(parent)
    def __init__(self, winTitle, slt=False, ansopts=None, parent=None):
        super(InputDialogWindow, self).__init__(parent)
        QDialog.__init__(self, parent)

        self.slt = slt
        print('slt --->', slt)
        layout = QFormLayout()

        if self.slt==False:
            self.lb = QLabel("Пожалуйста напишите 'ans' аттрибут:")
            self.le = QLineEdit()
            self.le.setPlaceholderText("option1**?**option2**?**option3")
            layout.addRow(self.lb,self.le)

        self.lb1 = QLabel("Пожалуйста напишите 'text' аттрибут:")
        self.le1 = QLineEdit()
        self.le1.setPlaceholderText("Это текст вашего вопроса")
        if self.slt==True:
            self.le1 = QPlainTextEdit()
        layout.addRow(self.lb1,self.le1)

        if winTitle=="Вторичный вопрос в 'questionnaire' вопроснике" and self.slt==False:
            self.lb3 = QLabel("Пожалуйста выберите 'g_ans':")
            #self.btn1.clicked.connect(self.gettext)
            self.cb0 = QComboBox()
            self.cb0.addItems(ansopts.split("**?**"))
            layout.addRow(self.lb3,self.cb0)
        elif self.slt==True:
            self.le1.setPlaceholderText("Текст ответа")
            self.lb3 = QLabel("Пожалуйста, выберите 'g_ans'")
            self.cb0 = QComboBox()
            self.cb0.addItems(ansopts.split("**?**"))
            layout.addRow(self.lb3, self.cb0)

        self.lb2 = QLabel("Пожалуйста, выберите 'type' тип вопроса")
        #self.btn1.clicked.connect(self.gettext)
        self.cb = QComboBox()
        self.cb.addItems(["rb", "le"])
        layout.addRow(self.lb2,self.cb)

        self.btn1 = QPushButton("Создать тег")
        self.btn1.clicked.connect( lambda: (self.validateInfo(self.slt)) )
        self.btn2 = QPushButton("Отмена")
        self.btn2.clicked.connect(self.reject)
        #self.btn2.clicked.connect(self.getint)
        layout.addRow(self.btn1,self.btn2)
        self.setLayout(layout)
        #self.setWindowTitle(windowTitle)

    def validateInfo(self, sltCheck=False):
        print('проверка информации которая была введена...')
        if (sltCheck==True and self.le1.toPlainText()):
            self.accept()
        elif (sltCheck==False and self.le1.text() and self.le.text()):
            self.accept()
        else:
            QMessageBox.warning(self, "Недостаточно информации", "Пожалуйста, введите все поля",buttons=QMessageBox.Close, defaultButton=QMessageBox.Close)