from ossaudiodev import control_labels
from signal import pause
from gpiozero import DistanceSensor
from signal import pause
from bluedot import BlueDot
from EchoBot import BotGuarning
import RPi.GPIO as GPIO
import time
import board
import busio
import digitalio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306
from gpiozero import LED
import subprocess

contador_vasos = 0 #Variable donde se guardan el numero total de vasos

#Función encargada de gestionar todo el funcionamiento de la maquina de refrescos
def ControlProyecto(contador_vasos):
    servoPIN =26 #Pin de control para el servo
    #Configuración incial del servo
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(servoPIN, GPIO.OUT)
    p2 = GPIO.PWM(servoPIN, 50)
    p2.start(12)

    #Objeto para controlar el bluedot
    bd=BlueDot()

    #PARA LEDS pines
    #led de ultrasonico cuando esta en espera
    led_rojo=LED(10)
    #led del  servo
    led_verdeS=LED(22)
    #led del ultrasonico cuando funciona
    led_verdeU=LED(9)
    #Configuración inicial del motor
    ini=23
    ena=24
    #PARA sensor pines
    trig=17
    echo=18
    #Configuración inicial de sensor y motor
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(ini,GPIO.OUT)
    GPIO.setup(ena,GPIO.OUT)
    GPIO.setup(trig,GPIO.OUT)
    GPIO.setup(echo,GPIO.IN)
    p=GPIO.PWM(ena,1000)
    p.start(25)

    #------------------------------------------para el oled
    # Define el reseteo del pin
    oled_reset = digitalio.DigitalInOut(board.D4)
    #Función con la logia de operacion del servo destinado a la apertura del deposito de hielos
    def dpad(pos):
        if pos.top:
            p2.ChangeDutyCycle(1) #Valor que abre el servo 0 grados equivale
            time.sleep(0.5) #Espera de medio segundo
            print("abierto")
            led_verdeS.on() #Enciende el led verde
        elif pos.bottom:
            p2.ChangeDutyCycle(12) #Valor que cierra el servo 180 grados equivale
            time.sleep(0.5) #Espera de medio segundo
            print("cerrado")
            led_verdeS.off() #Apaga el led verde

    # Parametros del display
    WIDTH = 128
    HEIGHT = 64
    BORDER = 5

    # Protocolo IC2 para la comunicación con el OLED
    i2c = board.I2C()
    oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C, reset=oled_reset)

    # Limpiar el display
    oled.fill(0)
    oled.show()

    # Crea un espacio de dibujado
    # Establece el color y los parametros de la ventana en el oled
    image = Image.new("1", (oled.width, oled.height))

    # Se obtiene el obejeto de dibujo apra dibujar sobre el Panel
    draw = ImageDraw.Draw(image)

    # Dibuja un fondo
    draw.rectangle((0, 0, oled.width, oled.height), outline=255, fill=255)
    #Establece la fuente
    font = ImageFont.truetype('PixelOperator.ttf', 16)

    #Espera que se aprieta el boton de bluedot para el manejo del servo
    bd.when_pressed = dpad

    #Cacha todas las excepciones que peudan producirse y altera el funcionamiento
    try:
        while True:
            #--ACCION OLED
            #--ACCION SENSOR
            GPIO.output(trig,GPIO.LOW)
            time.sleep(0.5)

            GPIO.output(trig,GPIO.HIGH)
            time.sleep(0.00001)
            GPIO.output(trig,GPIO.LOW)

            #Mantien la escucha del sensor
            while True:
                pulso_inicio=time.time()
                if(GPIO.input(echo)==GPIO.HIGH):
                    break

            #Dispara la señal ultrasonica
            while True:
                pulso_fin=time.time()
                if(GPIO.input(echo)==GPIO.LOW):
                    break
            #Calculos para la distancia del vaso
            duracion=pulso_fin-pulso_inicio
            distancia=34300*duracion/2
            print("Distancia :",distancia)

            #---ACCION MOTOR
            if distancia<7:
                #Leds de estados de operación
                led_verdeU.on()
                led_rojo.off()
                print("sirviendo refresco")
                estado = 'Sirviendo' #El estado que se envia al bot de telegram
                GPIO.output(ini,GPIO.HIGH)
                # Dibuja el mensaje de que se esta sirviendo algo
                draw.rectangle((0, 0, oled.width, oled.height), outline=0, fill=0)
                draw.text((0, 0), "Sirviendo refresco" , font=font, fill=255)
                # Muestra el mensaje
                oled.image(image)
                oled.show()
                contador_vasos = contador_vasos + 1 #esta es la variable que cuenta el numero de vasos servidos
                time.sleep(.1)
            else:
                #Leds de estados de operación
                led_verdeU.off()
                led_rojo.on()
                print("esperando refresco")
                estado = 'En espera' #El estado que se envia al bot de telegram
                GPIO.output(ini,GPIO.LOW)
                # Dibuja el mensaje de que se ha quitado el vaso (no se sirve nada)
                draw.rectangle((0, 0, oled.width, oled.height), outline=0, fill=0)
                draw.text((0, 0), "Quitaste el vaso " , font=font, fill=255)
                #Muestra el mensaje
                oled.image(image)
                oled.show()
                time.sleep(.1)

    except KeyboardInterrupt:
        GPIO.cleanup() #Limpia los procesos que puedan quedarswe atorados en lso pines
        p.stop() #Para el motor ante cualquier anomalia
    return contador_vasos, estado #Retonar las variables para el bot

#Manda a llamar todo el codigo de control
def main():
    ControlProyecto()
    BotGuarning()


# Gregory-Leibniz formula for 'pi'
# http://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80
def calcPi(n):
    pi,numer = 0,4.0
    for i in range(n):
        denom = (2*i+1)
        term = numer/denom
        if i%2:
            pi -= term
        else:
            pi += term
    return(pi)

# here we use 16000 terms - try higher numbers, and lower ones too
print(calcPi(999999))


# 53. 最大子序和
# 给定一个整数数组 nums ，找到一个具有最大和的连续子数组（子数组最少包含一个元素），返回其最大和。

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        if n == 0:
            return 0
        return self.__max_sub_array(nums, 0, n - 1)

    def __max_sub_array(self, nums, left, right):
        if left == right:
            return nums[left]
        mid = left + (right - left) // 2
        return max(self.__max_sub_array(nums, left, mid),
                   self.__max_sub_array(nums, mid + 1, right),
                   self.__max_cross_array(nums, left, mid, right))

    def __max_cross_array(self, nums, left, mid, right):
        """
        一定包含 nums[mid] 元素的最大连续子数组的和
        思路是看看左边扩散到底，得到一个最大数
        右边扩散到底得到一个最大数
        :param nums:
        :param mid:
        :param right:
        :return:
        """
        ls = 0
        j = mid - 1
        s1 = 0
        while j >= left:
            s1 += nums[j]
            ls = max(ls, s1)
            j -= 1

        rs = 0
        j = mid + 1
        s2 = 0
        while j <= right:
            s2 += nums[j]
            rs = max(rs, s2)
            j += 1
        return ls + nums[mid] + rs

if __name__ == '__main__':
    s = Solution()
    nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
    result = s.maxSubArray(nums)
    print(result)


class Solution:
    def findRepeatedDnaSequences(self, s: str) -> List[str]:
        cache = {}
        res = set()
        for i in range(len(s)-9):
            key = s[i:i+10]
            if key in cache:
                res.add(key)
            cache[key] = cache.get(key, 0) + 1
        return res


#####################################
# Developed by Baptiste PICARD      #
# picard.baptiste@laposte.net       #
# Started the 11th of April 2020    #
# picard.baptiste@laposte.net       #
#                                   #
#####################################

# Imports
# Librairies
import json
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# Modules
from account import *
from access import *
from utils import *
from maths import *

class Stock() :
	# Constructor
	def __init__(self, name, api_key, json, money) :
		self.stock_name = name
		self.api_key = api_key
		self.json = json
		self.money = money
		self.date = None
		self.day_ago = None
		self.week_ago = None
		self.month_ago = None
		self.df = None
		self.account = Account(name, json)
		self.create()

	# Getters / Setters
	def getStockName(self) :
		return self.stock_name

	def getAPI(self) :
		return self.api_key

	def getJson(self) :
		return self.json

	def getDate(self) :
		return self.date

	def getMoney(self) :
		return self.money

	def getAccount(self) :
		return self.account

	def getDayAgo(self) : # get the different values (day ago) of a stock  (open price, lowest price, highest price, volume, close price : dict)
			return self.day_ago

	def getWeekAgo(self) : # get the different values (day ago) of a stock  (open price, lowest price, highest price, volume, close price : dict)
			return self.week_ago

	def getMonthAgo(self) : # get the different values (day ago) of a stock  (open price, lowest price, highest price, volume, close price : dict)
			return self.day_ago

	def getDF(self) :
		return self.df

	def setDF(self, value) :
		self.df = value

	# Functions
	# Creation
	def createDates(self) :
		if(self.getDate() == None) :
			self.date = str(dt.datetime.strptime(list(getIntraday(self.getStockName(), self.getAPI()).keys())[0], "%Y-%m-%d %H:%M:%S").date())
		if(self.getDayAgo()==None or self.getMonthAgo()==None or self.getWeekAgo()==None) :
			DA, dDA, WA, dWA, MA, dMA = getStockOldValues(self.getStockName(), self.getAPI())
			if(DA!=None or WA!=None or MA!=None or dDA!=None or dWA!=None or dMA!=None) :
				self.day_ago = {'date' : dDA, 'open' : float(DA['1. open']), 'close' : float(DA['4. close']), 'high' : float(DA['2. high']), 'low' : float(DA['3. low'])}
				self.week_ago = {'date' : dWA, 'open' : float(WA['1. open']), 'close' : float(WA['4. close']), 'high' : float(WA['2. high']), 'low' : float(WA['3. low'])}
				self.month_ago = {'date' : dMA, 'open' : float(MA['1. open']), 'close' : float(MA['4. close']), 'high' : float(MA['2. high']), 'low' : float(MA['3. low'])}
			print("All dates were created.")
			return 0
		else :
			return -1

	def createJson(self) :
		data = {'stock' : self.getStockName(),'buy' : [], 'sell' : [], 'money' : self.getMoney(), 'amount' : 0 }
		if(not os.path.exists(self.getJson())) :
			f = open(self.getJson(),"w")
			json.dump(data, f)
			f.close()
			print('File {} created.'.format(self.getJson()))
		else :
			json_data = open(self.getJson())
			json_data = json.load(json_data)
			if(json_data.keys() == data.keys()) :
				print('File {} seems to be already exists.'.format(self.getJson()))
			else :
				return -1

	def create(self) :
		self.createDates()
		self.createJson()

	# Updating
	def update(self) :
		print("Updating the stock : {} -> {}.".format(self.getStockName(), self.getDate()))
		df = pd.DataFrame(data=getIntraday(self.getStockName(), self.getAPI())).transpose()
		df['day'] = pd.to_datetime(df.index).strftime('%Y-%m-%d')
		df = df[df['day'] == self.getDate()]
		df['time'] = pd.to_datetime(df.index).strftime('%H:%M:%S')
		df = df.astype({'1. open' : 'float64', '2. high' : 'float64', '3. low' : 'float64', '4. close' : 'float64', '5. volume' : 'int'})
		df = df.sort_values(by='time', ascending=True)
		df = df.reset_index(drop=True)
		df['id'] = df.index
		self.setDF(df)

	# Shwoing
	def show(self, buy_sell_pts=False, labels=True, line_labels=False, curve_fiting=False, interpolation=False, max_min=False, sockets=True, meanTrend=True, volumes=False) :
		print("Showing the stock price evolution : {}.".format(self.getStockName()))
		if(not self.getDF().empty) :
			df = self.getDF()
			ticks_range = np.arange(0, df.shape[0], 10)
			plt.figure(figsize=(19, 11))
			plt.title("Representation of {} stocks evolution the {}.".format(self.getStockName(),  self.getDate()))
			plt.xticks(ticks_range, df['time'][ticks_range], rotation='vertical')
			plt.ylim((df['3. low'].min()-1, df['2. high'].max()+1))
			sns.lineplot(x=df['id'], y=df['4. close'], markers=True, dashes=False)
			if(curve_fiting) :
				predict_x, predict_y, coefs = getCurvePolyFit(df['id'], df['4. close'], degree=15)
				sns.lineplot(x=predict_x, y=predict_y, markers=True, dashes=False) # Curve fitting
			if(interpolation) :
				interp_x, interp_y = getCurveInterp(df['id'], df['4. close'])
				sns.lineplot(x=interp_x, y=interp_y, markers=True, dashes=False) # Curve interpolation
			if(buy_sell_pts == True) :
				x_b, x_s = self.getAccount().getBuyingIds(), self.getAccount().getSellingIds()
				y_b = [float(df[df['id'] == item]['4. close'].values) for item in x_b]
				y_s = [float(df[df['id'] == item]['4. close'].values)  for item in x_s]
				plt.plot(x_b, y_b, 'rx') # plot buy points
				plt.plot(x_s, y_s, 'gx') # plot sell points
			if(labels) :
				plt.text(df['id'].iloc[-1] + 3, df['4. close'].iloc[-1], 'Last : '+str(df['4. close'].iloc[-1])) # Last
				plt.text(df['id'].iloc[-1] + 3, df['3. low'].min(), 'Lowest : '+str(df['3. low'].min())) # Lowest
				plt.text(df['id'].iloc[-1] + 3, df['2. high'].max(), 'Highest : '+str(df['2. high'].max())) #  Highest
				# plt.text(df['id'].iloc[-1] + 3, df['4. close'].iloc[-1]  - 0.2, 'Mean : '+str(df['4. close'].mean())) # Mean
			if(line_labels) :
				sns.lineplot(x=df['id'], y=df['3. low'].min()) # Lowest
				sns.lineplot(x=df['id'], y=df['2. high'].max()) # Highest
				sns.lineplot(x=df['id'], y=df['4. close'].mean()) # Mean
			if(max_min) :
				max_x, max_y = localMaximas(df['id'], df['4. close'], n_pts=1)
				min_x, min_y = localMinimas(df['id'], df['4. close'], n_pts=1)
				plt.plot(max_x, max_y, 'ro') # plot the local maximums
				plt.plot(min_x, min_y, 'bo') # plot the local minimums
			if(sockets) :
				mi, ma, _, _ = socketTrends(df)
				if mi.size!= 0:
					sns.lineplot(x=df['id'], y=mi.reshape(1, -1).tolist()[0], markers=True, dashes=False)
				if ma.size!= 0:
					sns.lineplot(x=df['id'], y=ma.reshape(1, -1).tolist()[0], markers=True, dashes=False)
			if(meanTrend) :
				mean_x, mean_y = meanTrend(df)
				sns.lineplot(x=mean_x, y=mean_y)
			if(volumes) :
				V_std = (df['5. volume'] - df['5. volume'].min()) / (df['5. volume'].max() - df['5. volume'].min()) * 2
				V_scaled = V_std * (df['4. close'].max() - df['4. close'].min()) + df['4. close'].min() - 1
				plt.text(df['id'].iloc[-1] + 3, V_scaled.max(), 'Max Volume : '+str(df['5. volume'].max())) # Last
				plt.text(df['id'].iloc[-1] + 3, V_scaled.min(), 'Min Volume : '+str(df['5. volume'].min())) # Lowest
				sns.lineplot(x=df['id'], y=V_scaled)
			plt.xlabel("Time")
			plt.ylabel("Stock price")
			plt.show()
		else :
			print("Can't draw the figure.")

	# Other function
	def buyStrategy(self, sell_threshold=0.002) :
		print("Trying to buy some "+self.getStockName()+" stocks.")
		df = self.getDF()
		if(self.getAccount().checkStock()) :
			buy_flag = False
		else :
			buy_flag = True
		previous_item = self.getDF()['1. open'].iloc[0]
		for index_item, item in df.iterrows() :
			if(index_item == 0) :
				pass
			else :
				r = np.arange(0, index_item+1, 1)
				max_x, max_y = localMaximas(df['id'][r].values, df['4. close'][r].values)
				min_x, min_y = localMinimas(df['id'][r].values, df['4. close'][r].values)
				if(buy_flag==True) : # If the buying_flag is set to True.
					if(previous_item<item['4. close']): # Ascending curve.
						if(min_y.size!=0 and (max_y.size==0 or max_x[-1]<min_x[-1])) : # The last local min/max is a minimum.
							if(buyLimit(time=item['time'])) : # If the last time to buy isn't overtaken.
								new_values_y_min, new_values_y_max, lr_min, lr_max = socketTrends(df.loc[df['id'].isin(r)])
								if(lr_min == 0 or new_values_y_min == np.array([])) :
									pass
								elif(item['4. close'] <= df.loc[df['id'].isin(r)]['4. close'].quantile(0.25) and item['4. close'] < lr_min.predict(np.array(item['id']).reshape(-1, 1))[0][0]) : # filter
									self.getAccount().buy(item)
									buy_flag = False
				elif(buy_flag==False) :
					if(previous_item>item['4. close']) : # Descending curve and self.getLastBuyingPrice()!=None
						if(max_y.size!=0 and (min_y.size==0 or max_x[-1]>min_x[-1])) : # The last local min/max is a maximum
							if(self.getAccount().checkStock()) : # We have something to sell and the buying_flag is set to False
								new_values_y_min, new_values_y_max, lr_min, lr_max = socketTrends(df.loc[df['id'].isin(r)])
								if(lr_max == 0 or new_values_y_max == np.array([])) :
									pass
								elif(item['4. close'] >= df.loc[df['id'].isin(r)]['4. close'].quantile(0.75) and item['4. close'] >= self.getAccount().getLastBuyingPrice() and item['4. close'] >= 0.85 * lr_max.predict(np.array(item['id']).reshape(-1, 1))[0][0]) : #filter
									self.getAccount().sell(item)
									buy_flag = True
				previous_item = item['4. close']

	# Test function
	def test(self) :
		print("Test on the stock : {}.".format(self.getStockName()))
		socketTrends(self.getDF())


from django.core.exceptions import ValidationError
from django.utils.deconstruct import deconstructible

DOMAINS = ('gmail.com', 'yahoo.com')

def validate_email_domain(value):       # email_name@domain.com  --> ['email_name', 'domain.com']
    # domains = ('gmail.com', 'yahoo.com')
    domain = value.split('@')[-1]
    # if domain not in domains:
    if domain not in DOMAINS:
        raise ValidationError(f'Emails domain "{domain}" is not correct.')

@deconstructible
class ValidateEmailDomain:
    def __init__(self, *domains):
        if domains:
            self.domains = tuple(domains)
        else:
            self.domains = DOMAINS

    def __call__(self, *args, **kwargs):
        domain = args[0].split('@')[-1]
        if domain not in self.domains:
            raise ValidationError(f'Emails domain "{domain}" is invalid.')


#!/usr/bin/env python

import os
from glob import glob

basepath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                        "examples")

template = """\
.. _ex-{name}:

Example: `compapp.samples.{name}`
----------------------------------------------------------------------

.. literalinclude:: {path}

.. plot::

   from compapp.samples.{name} import MyApp
   MyApp({{'figure': {{'autoclose': False}}}}).execute()

"""

def generate_rst_file(rstpath, pypath):
    name = os.path.splitext(os.path.basename(pypath))[0]
    path = os.path.relpath(pypath, os.path.dirname(rstpath))
    with open(rstpath, 'w') as file:
        file.write(template.format(**locals()))

def makerst(path, rst_dir):
    if not path:
        path = glob(os.path.join(basepath, "code", "*.py"))
        path = [p for p in path if not p.endswith('__init__.py')]

    for pypath in path:
        name = os.path.splitext(os.path.basename(pypath))[0]
        rstpath = os.path.join(rst_dir, name) + '.rst'
        generate_rst_file(rstpath, pypath)

def main(args=None):
    import argparse
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("--rst-dir", default=basepath,
                        help="generate rst files here")
    parser.add_argument("path", nargs='*')
    ns = parser.parse_args(args)
    makerst(**vars(ns))

if __name__ == '__main__':
    main()


from random import randint
import shutil

class Reader:
    #Клас що являє собою бінарний файл і два вказівники: теперішній і наступний
    def __init__(self, path: str):
        self.path = path
        self.f = open(path, "rb")
        self.curr = self.f.read(32)
        self.next = self.f.read(32)

    def close(self):
        self.f.close()

    def __iter__(self):
        return self

    def __next__(self):
        #Повернення теперішнього вказівника і зсув вказівників на 1
        tmp = self.curr
        self.curr = self.next
        self.next = self.f.read(32)
        return tmp

class Sorter:
    def __init__(self, path_a: str, path_b: str, path_c: str):
        #Файли В та С чисті, файл А ні
        self.path_a = path_a
        self.path_b = path_b
        self.path_c = path_c
        self._clear(path_b)
        self._clear(path_c)

    def create_random_file(self, n: int, max_n: int):
        with open(self.path_a, "wb") as a:
            for i in range(n):
                a.write(randint(1, max_n).to_bytes(32, byteorder="big"))

    def copy_from_file(self, path: str):
        shutil.copy(path, self.path_a)

    def sort(self):
        while not self._is_sorted():
            self._distribute()
            self._merge()

    def __str__(self):
        a, b, c = "A: " + self._read(self.path_a), "B: " + self._read(self.path_b), "C: " + self._read(self.path_c)
        return "\n".join([x for x in [a, b, c] if x])

    def _distribute(self):
        a = Reader(self.path_a)
        b = open(self.path_b, "wb")
        c = open(self.path_c, "wb")
        i = True
        while a.curr:
            b.write(a.curr) if i else c.write(a.curr)
            if a.curr > a.next:
                i = not i
            next(a)
        a.close(), b.close(), c.close()

    def _merge(self):
        """
        Злиття відповідних серій
        Логіка наступна:
            Якщо обидва числа не в кінці серії, знаходимо з них менше, дописуємо і посуваємо покажчик,
            таким чином зливаючи ці серії
            Інакше:
            Якщо число файлу В в кінці серії, то ми дозливаємо актуальну серію файла В і залишки
            серії файла С, тобто якщо число із файла С менше, його дописуємо, як тільки меншим
            виявиться наше останнє число серії із файла В, то це число дописуємо, і всі інші
            числа із серії із файла С також дописуємо аж до кінця серії. Після цієї операції обидва
            покажчика будуть на початку нової серії.
            Аналогічно якщо число файлу С в кінці серії.
            Якщо ж обидва числа в кінці серії, дописуємо їх по зростанню і зсуваємо покажчик на крок уперед,
            в результаті обидва покажчики на початку серії
            Якщо вони у кінці фалу, дописуємо залишок іншого файлу
        """
        a = open(self.path_a, "wb")
        b = Reader(self.path_b)
        c = Reader(self.path_c)
        while b.curr and c.curr:
            if b.curr <= b.next and c.curr <= c.next:
                if b.curr <= c.curr:
                    a.write(next(b))
                else:
                    a.write(next(c))
            elif b.curr >= b.next and c.curr <= c.next:
                while c.curr <= c.next:
                    if b.curr <= c.curr:
                        a.write(next(b))
                        while c.curr <= c.next:
                            a.write(next(c))
                        a.write(next(c))
                        break
                    else:
                        a.write(next(c))
            elif c.curr >= c.next and b.curr <= b.next:
                while b.curr <= b.next:
                    if c.curr <= b.curr:
                        a.write(next(c))
                        while b.curr <= b.next:
                            a.write(next(b))
                        a.write(next(b))
                        break
                    else:
                        a.write(next(b))
            else:
                if c.curr <= b.curr:
                    a.write(c.curr)
                    a.write(b.curr)
                else:
                    a.write(b.curr)
                    a.write(c.curr)
                next(c), next(b)

        if not b.curr and c.curr:
            while c.curr:
                a.write(next(c))
        elif not c.curr and b.curr:
            while b.curr:
                a.write(next(b))
        a.close(), b.close(), c.close()

    def _is_sorted(self):
        """Перевірка чи файл А відсортований"""
        a = Reader(self.path_a)
        while a.next:
            if a.curr > a.next:
                a.close()
                return False
            next(a)
        a.close()
        return True

    @staticmethod
    def _read(path: str) -> str:
        """Читання перших 30 чисел з файла, ставлячи '|' в кінці кожної серії"""
        s = ""
        f = Reader(path)
        for _ in range(30):
            if not f.curr:
                break
            s += str(int.from_bytes(f.curr, byteorder="big")) + " "
            if f.curr > f.next:
                s += "| "
            next(f)
        f.close()
        return s

    @staticmethod
    def _clear(path: str):
        with open(path, "wb"):
            pass


from pathlib import Path

from rdflib import RDF, Graph
from rdflib.namespace import FOAF

EXAMPLES_DIR = Path(__file__).parent

if __name__ == "__main__":
    graph = Graph()
    graph.parse(f"{EXAMPLES_DIR / 'foaf.n3'}", format="n3")

    for person in graph[: RDF.type : FOAF.Person]:  # type: ignore[misc]
        friends = list(graph[person : FOAF.knows * "+" / FOAF.name])  # type: ignore[operator]
        if friends:
            print(f"{graph.value(person, FOAF.name)}'s circle of friends:")
            for name in friends:
                print(name)


#DFS 메소드 정의
def dfs(graph, v, visited):
    print(visited)
    #현재 노드를 방문처리
    visited[v] = 1
    print(v, end=' ')
    #현재 노드와 연결된 다른 노드를 재귀적으로 방문
    for i in graph[v]:
        if not visited[i]:
            dfs(graph, i, visited)

#각 노드가 연결된 정보를 표현 (2차원 리스트)
graph = [
    [1,2], #0번 노드에서 1과 2로 이동 가능하다.
    [3, 4, 5], #1번 노드에 연결된 건 2,3,8 이다.
    [6,7], #2번 노드에 연결된 건 1,7이다.
    [8],
    [3],
    [],
    [],
    [],
    []
]

#각 노드가 방문된 정보를 표현 (1차원 리스트)
visited = [0] * 9

dfs(graph, 0, visited)   #출력 : 0 1 3 8 4 5 2 6 7


import random
import util
'''
'' Given an array of positive integers A with N numbers and another positive integer S, write a function that
'' finds slices of A with consecutive indices such that the sum of this slice is S and outputs the number of such possible slices
'''

a_10 = random.sample(range(1, 11), 10)
a_100 = random.sample(range(1, 1000), 100)
a_1000 = random.sample(range(1, 10000), 1000)

def create_slices(A, N):

    slices = []

    for i_idx, i in enumerate(A):
        total = i
        slice = [i]

        # If the number is equal to N then we found the slice and index
        if total == N:
            slices.append(slice)
            continue

        for j_idx, j in enumerate(A):
            '''
            '' Skill all previouse elements
            '''
            if j_idx <= i_idx:
                continue

            total = total + j
            slice.append(j)

            '''
            '' Break loop if total is greater then required
            '''
            if total > N:
                slice = []
                break

            if total == N:
                break

        if slice:
            total = sum(slice)
            '''
            '' To make sure only valid slices are added
            '''
            if total == N:
                slices.append(slice)

    return slices

start_time = util.get_start_time()
print(create_slices(a_10, 7))
util.print_end_time(start_time)

start_time = util.get_start_time()
print(create_slices(a_100, 200))
util.print_end_time(start_time)

start_time = util.get_start_time()
print(create_slices(a_1000, 250))
util.print_end_time(start_time)

'''
Output
[[4, 3], [6, 1], [7], [5, 2]]
0.127 milliseconds
[]
1.085 milliseconds
[[250]]
97.22200000000001 milliseconds
'''


import sys

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class Konversi(QWidget):
    def __init__(self):
        super().__init__()
        self.setupUi()

    def setupUi(self):
        self.resize(300, 150)
        self.move(300, 300)
        self.setWindowTitle('Konversi Kg')#Nama Window

        self.label1 = QLabel()
        self.label1.setText(' Konversi KG! ')
        self.label2 = QLabel()
        self.label2.setText('Masukkan Berat (dalam Kg) : ')
        self.berat = QLineEdit()
        self.berat.setValidator(QIntValidator())#agar angka yang diketikkan menjadi Integer
        self.cekOns = QRadioButton()
        self.cekOns.setText('&ons')
        self.cekOns.setChecked(True)
        self.cekTon = QRadioButton()
        self.cekTon.setText('&ton')
        self.cekG = QRadioButton()
        self.cekG.setText('&g')
        self.cekKuintal = QRadioButton()
        self.cekKuintal.setText('&kuintal')

        self.resultLabel = QLabel('Hasil: ')#menambilkan hasil dengan tampilan label
        self.checkButton = QPushButton('Konversi!')#nama PushButton

        Layout = QGridLayout()#layout pada label 1 dan 2
        Layout.addWidget(self.label1,0,0)
        Layout.addWidget(self.label2,1,0)
        Layout.addWidget(self.berat,1,1)

        hbox = QHBoxLayout()#layout horizontal untuk RadioButton
        hbox.addWidget(self.cekOns)
        hbox.addWidget(self.cekTon)
        hbox.addWidget(self.cekG)
        hbox.addWidget(self.cekKuintal)

        layout = QVBoxLayout()#layout vertikal untuk layout,horizontal,result label dan check button
        layout.addLayout(Layout)
        layout.addLayout(hbox)
        layout.addWidget(self.resultLabel)
        layout.addWidget(self.checkButton)
        layout.addStretch()

        self.setLayout(layout)
        self.checkButton.clicked.connect(self.checkButtonClick)#memanggil/membuat koneksi

    def checkButtonClick(self): #method
        berat = float(self.berat.text())
        if self.cekOns.isChecked():
            hasil = berat*10
            self.resultLabel.setText(' Hasil Ons : '+str(hasil))
        elif self.cekTon.isChecked():
            hasil = berat/1000
            self.resultLabel.setText(' Hasil Ton : '+str(hasil))
        elif self.cekG.isChecked():
            hasil = berat*1000
            self.resultLabel.setText(' Hasil Gram : '+str(hasil))
        else:
            hasil = berat/100
            self.resultLabel.setText(' Hasil Kuintal : '+str(hasil))

if __name__ == '__main__':
    a = QApplication(sys.argv)
    form = Konversi()
    form.show()

    a.exec_()


# given an array of numbers and a number 'K', we need to remove 'k' numbers from array
# such that we are left with max distinct numbers

'''
1) need to find frequencies of all the numbers
2) push all numbers that are not distinct in min heap based on frequency, same time count no of all
distinct numbers
3) follow greedy approach, in stepwise fashion, we will remove the least frequent number from heap
(i.e top element of min heap) and try to make it disticnt. we will see if we can remove all the
occurrences of a number except one. If we can, we will increment our running count of distinct numbers.
We have to keep a count of how many removals we have done.

4) if removing elements from heap, we are still left with some deletions, we have to remove some
distinct elements.

'''
from heapq import *
def max_distinct_elements(arr, k):

    distinctElementsCount = 0
    #base case
    if len(arr) <= k:
        return distinctElementsCount

    # find frequency of numbers
    frequencyMap = {}

    for num in arr:
        if num in frequencyMap:
            frequencyMap[num]+=1
        else:
            frequencyMap[num] = 1

    minHeap = []
    #insert the elements whose frequency is greater than 1 into min heap

    for num, frequency in frequencyMap.items():
        if frequency ==1:
            distinctElementsCount +=1
        else:
            heappush(minHeap, (frequency, num))

    # following a greedy approach, try removing least frequency numbers first from min-heap

    while k>0 and minHeap:

        frequency, num = heappop(minHeap)

        # to make element distinct, we need to remove all of its occurrences except one

        k -= frequency - 1
        if k>=0:
            distinctElementsCount+=1

    # if k>0, this means we have to remove some distinct elements
    if k > 0 :
        distinctElementsCount -= k

    return distinctElementsCount

if __name__=="__main__":
    arr = [7,3,5,8,5,3,3]
    k=2
    print(max_distinct_elements(arr, k))


from intcode import IntcodeVm
import time
import curses
import itertools
from collections import Counter

def parse_grid(vm):
    grid = []
    row = []
    for c in vm.run():
        c = str(chr(c))
        if c == '\n':
            if row: grid.append(row)
            if len(grid) == 43: break
            row = []
            continue
        row.append(c)
    return grid

def draw_grid(screen, grid, extra=[]):
    screen.addstr(0,0, '   ' + ' '.join([str((i//10) % 10) for i in range(len(grid[0]))]))
    screen.addstr(1,0, '   ' + ' '.join([str(i % 10) for i in range(len(grid[0]))]))
    for i, r in enumerate(grid):
        screen.addstr(i+2, 0, (' ' if i < 10 else '') + str(i) + ' ' + ' '.join(r))
    if lines:
        for i, l in enumerate(lines):
            screen.addstr(i+len(grid)+2, 0, l)

    screen.refresh()

def find_intersections(grid):
    points = []
    for i, r in enumerate(grid):
        for j, p in enumerate(r):
            if p == '#':
                if (i+1 < len(grid) and grid[i+1][j] == '#' and
                    j+1 < len(r)    and grid[i][j+1] == '#' and
                    i-1 > 0         and grid[i-1][j] == '#' and
                    j-1 > 0         and grid[i][j-1] == '#'):
                    points.append((i,j))
    return points

def find_path(grid):
    for i, r in enumerate(grid):
        for j, p in enumerate(r):
            if p == '^': x, y = j, i
    dx = [0, 1, 0, -1]
    dy = [-1, 0, 1, 0]
    dirs = []
    c = -1
    l = 'L'
    d = 3
    while True:
        c+=1
        nx, ny = x + dx[d], y + dy[d]
        if 0 <= nx < len(grid[0]) and 0 <= ny < len(grid) and grid[ny][nx] == '#':
            x, y = nx, ny
            continue
        if y+1 < len(grid) and grid[y+1][x] == '#':
            if (x, y+1) != (x-dx[d], y-dy[d]):
                dirs.append((l, c))
                l = 'R' if d == 1 else 'L'
                d = 2
                c = 0
                x, y = x, y + 1
                continue
        if 0 <= y-1 and grid[y-1][x] == '#':
            if (x, y-1) != (x-dx[d], y-dy[d]):
                dirs.append((l, c))
                l = 'L' if d == 1 else 'R'
                d = 0
                c = 0
                x, y = x, y - 1
                continue
        if x+1 < len(grid[0]) and grid[y][x+1] == '#':
            if (x+1, y) != (x-dx[d], y-dy[d]):
                dirs.append((l, c))
                l = 'R' if d == 0 else 'L'
                d = 1
                c = 0
                x, y = x+1, y
                continue
        if 0 <= x-1 and grid[y][x-1] == '#':
            if (x-1, y) != (x-dx[d], y-dy[d]):
                dirs.append((l, c))
                l = 'L' if d == 0 else 'R'
                d = 3
                c = 0
                x, y = x-1, y
                continue
        break
    dirs.append((l, c))
    return ''.join([l+str(d)for l,d in dirs])

def combine(instructions, mins, maxs):
    possible_matches = []
    matches = []
    for start_index in range(0, len(instructions)-3):
        for end_index in range(start_index+1, len(instructions)+1):
            current_string = instructions[start_index:end_index]
            if len(current_string) < mins: continue
            if len(current_string) > maxs: continue
            possible_matches.append(instructions[start_index:end_index])

    for possible_match, count in Counter(possible_matches).most_common():
        if count <= 1: break
        matches.append(possible_match)
    return list(filter(lambda m: len(m) <= 10, filter(is_valid_match, matches)))

def is_valid_match(match):
    return ((match[0] == 'L' or match[0] == 'R') and
            (match[-1] != 'L' and match[-1] != 'R'  and match[-1] != ',') and
            (match[-1] != '0' and match[-1] != '1'))

def find_strats(grid):
    instructions = find_path(grid)
    cs = combine(instructions, 4, 10)
    for perm in itertools.combinations(cs, 3):
        r = instructions
        for p in perm:
            r = r.replace(p, '')
        if len(r) == 0:
            r = instructions
            for i,p in enumerate(sorted(perm, reverse=True)):
                l = 'A' if i == 0 else 'B' if i ==1 else 'C'
                r = r.replace(p, l)
            return sorted(perm, key=len, reverse=True), r

# exit()
def a_strat():
    return 'L,10,L,10,L,4,L,6\n'

def b_strat():
    return 'L,6,R,12,L,6\n'

def c_strat():
    return 'R,12,L,10,L,4,L,6\n'

def main_strat():
    return 'B,C,B,C,B,A,C,A,B,A\n'

def video_strat():
    return 'y\n'

def start():
    for s in (main_strat() + a_strat() + b_strat() + c_strat() + video_strat()):
        yield ord(s)

def input_line(vm, strat):
    out = ''
    while True:
        c = vm.eval(strat)
        if c is None: assert False
        c = str(chr(c))
        if c == '\n':
            return out # + ''.join([str(chr(s)) for s in strat])
        out += c

def provide_input(vm, s):
    out = ''
    i = False
    while True:
        c = vm.eval()
        if c is None: assert False
        c = str(chr(c))
        if c == '\n':
            if not i:
                i = True
                out = ''
                continue
            break
        out += c
    lines = []
    lines.append(out + ' ' + main_strat()[:-1])
    lines.append(input_line(vm, s) + ' ' + a_strat()[:-1])
    lines.append(input_line(vm, s) + ' ' + b_strat()[:-1])
    lines.append(input_line(vm, s) + ' ' + c_strat()[:-1])
    lines.append(input_line(vm, s) + ' ' + video_strat()[:-1])
    input_line(vm, s), a_strat()
    return lines

def capture_video(screen, vm, lines):
    prev_grid = []
    curses.curs_set(0)
    grid = []
    row = []
    i = 0
    for c in vm.run():
        if c > 255:
            lines.append("Total Dust: " + str(c))
            draw_grid(screen, prev_grid, lines)
            time.sleep(10)
        c = str(chr(c))
        if c == '\n':
            if row: grid.append(row)
            if len(grid) == 43:
                draw_grid(screen, grid, lines)
                i = 0
                if grid != []: prev_grid = grid
                grid = []
            row = []
            continue
        row.append(c)
        i += 1
    curses.curs_set(1)

# Part 1
mem = IntcodeVm.parse_memory(open('input.txt').read())
mem[0] = 2
vm = IntcodeVm(mem)
grid = parse_grid(vm)
print(sum([x * y for x, y in find_intersections(grid)]))

# Part 2
print(find_strats(grid))
lines = provide_input(vm, start())
curses.wrapper(capture_video, vm, lines)


line = open("input.txt").read().rstrip()

def part_one():
    for i in range(len(line)):
        if len(set(line[i:i+4])) == 4:
            return i + 4

def part_two():
    for i in range(len(line)):
        if len(set(line[i:i+14])) == 14:
            return i + 14

print(part_one())
print(part_two())


"""

2409(easy)统计共同度过的日子数

Alice 和 Bob 计划分别去罗马开会。

给你四个字符串 arriveAlice ，leaveAlice ，arriveBob 和 leaveBob 。Alice 会在日期 arriveAlice 到 leaveAlice 之间在城市里（日期为闭区间），而 Bob 在日期 arriveBob 到 leaveBob 之间在城市里（日期为闭区间）。每个字符串都包含 5 个字符，格式为 "MM-DD" ，对应着一个日期的月和日。

请你返回 Alice和 Bob 同时在罗马的天数。

你可以假设所有日期都在 同一个 自然年，而且 不是 闰年。每个月份的天数分别为：[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 。

"""

def countDaysTogether(
    arriveAlice: str, leaveAlice: str, arriveBob: str, leaveBob: str
) -> int:
    datesOfMonths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    prefixSum = [0]
    for date in datesOfMonths:
        # prefixSum[-1]代表引用列表最后一个元素
        prefixSum.append(prefixSum[-1] + date)

    arriveAliceDay = calculateDayOfYear(arriveAlice, prefixSum)
    leaveAliceDay = calculateDayOfYear(leaveAlice, prefixSum)
    arriveBobDay = calculateDayOfYear(arriveBob, prefixSum)
    leaveBobDay = calculateDayOfYear(leaveBob, prefixSum)
    # 返回0和相差日期的最大值，省去if比较
    return max(
        0, min(leaveAliceDay, leaveBobDay) - max(arriveAliceDay, arriveBobDay) + 1
    )

def calculateDayOfYear(day: str, prefixSum: list[int]) -> int:
    month = int(day[:2])  # 前两位，即月份
    date = int(day[-2:])  # 后两位，即日期
    return prefixSum[month - 1] + date

arriveAlice = "08-15"
leaveAlice = "08-18"
arriveBob = "08-16"
leaveBob = "08-19"
print(countDaysTogether(arriveAlice, leaveAlice, arriveBob, leaveBob))


# 导入所需的库
import numpy as np
import matplotlib.pyplot as plt

# 设置随机种子
np.random.seed(0)

# 生成10次运行的结果，每次都有fpr和tpr
# 假设每次有100个点
fprs = []
tprs = []
for i in range(10):
    fpr = np.sort(np.random.rand(100)) # 随机生成fpr，并排序
    tpr = np.sort(np.random.rand(100)) # 随机生成tpr，并排序
    fprs.append(fpr)
    tprs.append(tpr)

# 计算每个点的平均值和标准差
mean_fpr = np.mean(fprs, axis=0)
mean_tpr = np.mean(tprs, axis=0)
std_fpr = np.std(fprs, axis=0)
std_tpr = np.std(tprs, axis=0)

# 绘制平均ROC曲线，并用plt.fill_between函数来填充误差范围
plt.plot(mean_fpr, mean_tpr, label='Mean ROC')
plt.fill_between(mean_fpr, mean_tpr - std_tpr,
                 mean_tpr + std_tpr,
                 alpha=0.2,
                 label='Error range')
plt.xlabel('False positive rate')
plt.ylabel('True positive rate')
plt.legend()
plt.show()


import numpy as np
import torch

@torch.no_grad()
def mixup(x, y, alpha=0.2):
	if alpha > 0:
		lam = np.random.beta(alpha, alpha)
	else:
		lam = 1

	mixed_x = lam * x + (1 - lam) * x.flip(dims=(0,))
	y_a, y_b = y, y.flip(dims=(0,))
	return mixed_x, y_a, y_b, lam

def mixup_criterion(criterion, pred, y_a, y_b, lam):
	return lam * criterion(pred, y_a) + (1 - lam) * criterion(pred, y_b)


import random

WIDTH = 650
HEIGHT = 500

rocket = Actor("small_rocket", (WIDTH/2, HEIGHT - 50))
shields = []
x = 50

for i in range(3):
    shield = Rect((x, 350), (120, 40))
    shields.append(shield)
    x += 210

enemies = []
aliens = ["alien2", "alien_ship2", "alien3"]
alienProjectiles = []

y = 80
index = 0
for j in range(3):
    x = 100
    row = []
    for i in range(5):
        alien = Actor(aliens[index], (x, y))
        alien.xspeed = 4
        row.append(alien)
        x += 50

    enemies.append(row)
    index += 1
    y += 40

score = 0
lives = 3

fired = False
projectile = Rect((rocket.x, rocket.y), (5, 10))

gameState = "start"

# pause buttons
pause = Actor("pause", (630, 20))
restart = Rect((WIDTH/2 - 75, 230), (150, 50))
continueButton = Rect((WIDTH/2 - 75, 150), (150, 50))
quitButton = Rect((WIDTH/2 - 75, 310), (150, 50))

# music and sounds
sound = Actor("volume", (WIDTH/2 - 50, 100))
soundOn = True
musicPlayer = Actor("music", (WIDTH/2+50, 100))
musicOn = True

music.play("tune.mp3")

def draw():
    screen.clear()

    if gameState == "play":
        rocket.draw()
        pause.draw()

        for p in alienProjectiles:
            screen.draw.filled_rect(p, (50, 255, 50))

        for e in range(len(enemies)):
            for s in range(len(enemies[e])):
                enemies[e][s].draw()

        for s in shields:
            screen.draw.filled_rect(s, (255, 255, 255))

        if fired:
            screen.draw.filled_rect(projectile, (255, 50, 50))

        screen.draw.text("Lives: " + str(lives), center=(50, 20), fontsize=30, color=(255, 255, 255))
        screen.draw.text("Score: " + str(score), center=(50, 50), fontsize=30, color=(255, 255, 255))

    elif (gameState == "start"):
        screen.draw.text("Press Enter to Start the Game!", center=(WIDTH/2, HEIGHT/2), fontsize=40, color=(255, 255, 255))

    elif (gameState == "end"):
        screen.draw.text("Game Over!\nPress Enter to Play Again \nor Escape to Quit!", center=(WIDTH/2, HEIGHT/2), fontsize=40, color=(255, 255, 255))

    else:
        sound.draw()
        musicPlayer.draw()
        screen.draw.text("Pause", center=(WIDTH/2, 50), fontsize=50, color=(255, 255,255))
        screen.draw.filled_rect(continueButton, (147,112,219))
        screen.draw.text("Continue", center=(WIDTH/2, 175), fontsize=30, color=(255, 255, 255))
        screen.draw.filled_rect(restart, (147,112,219))
        screen.draw.text("Restart", center=(WIDTH/2, 255), fontsize=30, color=(255, 255, 255))
        screen.draw.filled_rect(quitButton, (147,112,219))
        screen.draw.text("Quit", center=(WIDTH/2, 335), fontsize=30, color=(255, 255, 255))

def on_mouse_down(pos):
    global gameState, soundOn, musicOn

    if gameState == "play":
        if pause.collidepoint(pos):
            gameState = "pause"

    elif gameState == "pause":
        if continueButton.collidepoint(pos):
            gameState = "play"

        if restart.collidepoint(pos):
            gameState = "start"

        if quitButton.collidepoint(pos):
            quit()

        if sound.collidepoint(pos):
            if soundOn:
                sound.image = "no_volume"

            else:
                sound.image = "volume"

            soundOn = not soundOn

        if musicPlayer.collidepoint(pos):
            if musicOn:
                musicPlayer.image = "no_music"
                music.pause()
            else:
                musicPlayer.image = "music"
                music.unpause()
            musicOn = not musicOn

def on_key_down(key):
    global fired

    if key == keys.SPACE and not fired:
        fired = True

        if soundOn:
            sounds.laser.play()

def alienFire1():
    if len(enemies) >= 1:
        p1 = Rect((enemies[0][0].x, enemies[0][0].y), (5, 10))
        alienProjectiles.append(p1)

        if soundOn:
            sounds.laser2.play()

    clock.schedule_unique(alienFire2, 1.0)

def alienFire2():
    if len(enemies) >= 2:
        p2 = Rect((enemies[1][0].x, enemies[1][0].y), (5, 10))
        alienProjectiles.append(p2)

        if soundOn:
            sounds.laser2.play()

    clock.schedule_unique(alienFire3, 1.0)

def alienFire3():
    if len(enemies) >= 3:
        p3 = Rect((enemies[2][0].x, enemies[2][0].y), (5, 10))
        alienProjectiles.append(p3)

        if soundOn:
            sounds.laser2.play()

def updateAlienProjectiles():
    global lives

    for p in alienProjectiles:
        p.y += 5

        if rocket.colliderect(p):
            lives -= 1
            alienProjectiles.remove(p)

        if p.bottom >= HEIGHT:
            alienProjectiles.remove(p)

def resetAliens():
    enemies.clear()

    y = 80
    index = 0
    for j in range(3):
        x = 100
        row = []
        for i in range(5):
            alien = Actor(aliens[index], (x, y))
            alien.xspeed = 4
            row.append(alien)
            x += 50

        enemies.append(row)
        index += 1
        y += 40

def moveRocket():
    if keyboard.left and rocket.left > 0:
        rocket.x -= 10

    if keyboard.right and rocket.right < WIDTH:
        rocket.x += 10

def moveAliens():
    for e in range(len(enemies)):
        for s in range(len(enemies[e])):
            enemies[e][s].x += enemies[e][s].xspeed

def checkCollision():
    for e in enemies:
        if e[0].left <= 0:
            changeDirection()

        if e[len(e) - 1].right >= WIDTH:
            changeDirection()

def changeDirection():
    for e in range(len(enemies)):
        for s in range(len(enemies[e])):
            enemies[e][s].xspeed *= -1
            enemies[e][s].y += 1

def moveProjectile():
    projectile.y -= 10

def checkProjectileCollision():
    global fired, score

    for e in range(len(enemies)):
        for s in range(len(enemies[e])):
            if enemies[e][s].colliderect(projectile):
                fired = False
                enemies[e].pop(s)
                score += 5

                if len(enemies[e]) == 0:
                    enemies.pop(e)
                break

    if projectile.top <= 0:
        fired = False

def checkShieldCollision():
    global fired

    for s in shields:
        if s.colliderect(projectile):
            s.inflate_ip(-3, -1)
            fired = False

        for p in alienProjectiles:
            if p.colliderect(s):
                s.inflate_ip(-3, -1)
                alienProjectiles.remove(p)

def update():
    global gameState, lives

    if (gameState == "start" or gameState == "end"):
        if (keyboard.RETURN or keyboard.kp_enter):
            gameState = "play"
            lives = 3
            alienProjectiles.clear()
            resetAliens()
            clock.schedule_interval(alienFire1, 3.0)

        if (keyboard.escape):
            quit()

    elif (gameState == "play"):
        moveRocket()
        moveAliens()
        checkCollision()
        checkShieldCollision()
        updateAlienProjectiles()

        if len(enemies) == 0:
            resetAliens()

        if lives <= 0:
            gameState = "end"

        if fired:
            moveProjectile()
            checkProjectileCollision()
        else:
            projectile.x = rocket.x
            projectile.y = rocket.y - 20


from collections import defaultdict, deque
from itertools import permutations
from sys import stdin,stdout
from bisect import bisect_left, bisect_right
from copy import deepcopy

int_input=lambda : int(stdin.readline())
string_input=lambda : stdin.readline()
multi_int_input =lambda : map(int, stdin.readline().split())
multi_input = lambda : stdin.readline().split()
list_input=lambda : list(map(int,stdin.readline().split()))
string_list_input=lambda: list(string_input())
MOD = pow(10,9)+7

test= int_input()

for _ in range(test):
    n = string_input()
    result = set([])
    c = 0
    for i in range(len(n)):
        if i+2<len(n):
            if n[i]+n[i+1]+n[i+2] ==  "two":
                if i+4 <len(n):
                    if n[i+3] == "n" and n[i+4] == "e":
                        result.add(i+2)
                        c+=1
                    else:
                        result.add(i+1)
                        c+=1
                else:
                    result.add(i+1)
                    c+=1
            if n[i]+n[i+1]+n[i+2] ==  "one":
                if i not in result:
                    result.add(i+1)
                    c+=1

    print(c)
    for elements in result:
        print(elements+1,end = " ")
    print()


import numpy as np
from collections import deque
from itertools import count
from matplotlib.patches import Circle
import matplotlib
import matplotlib.pyplot as plt
from .math import length_squared, angle_between
from .area import Area
import time
from scipy.ndimage.interpolation import rotate
from .pedestriannumba import calculate_pedestrian_repulsive_force

class Pedestrian(object):
    """ Generate a pedestrian object.

    Generates a pedestrian and links it to the group. If start and/or
    target_path are not defined, it generates them from the spawn,
    target_path and target_area defined in the group.

    Args:
        pedestrian_id: unique id for this pedestrian
        group: the group to which this pedestrian is assigned
        desired_velocity: the desired velocity for this pedestrian
        relaxation_time: how quickly a pedestrian moves to their desired
            velocity
        start: a np.array([x,  y]) with the spawn point
        target_path: a list of np.array([x,  y]) objects that represents
            the path that this pedestrian should follow. If the pedestrian
            can see the next target in the list (meaning it is not
            obstructed from view by a wall) it will remove the previous
            target. Once the final target has been reached, the pedestrian
            will either be removed from the world or be given a new target
            within the target area.
    """
    _ids = count(0)

    def __init__(self, group, **kwargs):

        self.radius = 0.2
        self.mass = 60
        self.desired_velocity = 1.3
        self.maximum_velocity = 2.6
        self.relaxation_time = 0.5
        self.start = None
        self.target_path = []

        default_values = group.get_pedestrian_defaults()

        # Override default values
        for key, default_value in default_values.items():
            if key in kwargs:
                setattr(self, key, kwargs[key])
            else:
                setattr(self, key, default_value)

        if 'start' in kwargs:
            self.position = kwargs['start']
        else:
            self.position = group.generate_spawn()

        self.id = next(self._ids)
        self.group = group
        self.diameter = 2 * self.radius

        self.target_is_point = True
        self.angle_ou_process = False
        self.velocity_ou_process = False
        self.desired_offset_angle = 0.0
        self.desired_velocity_offset = 0.0
        self.closest_obstacle_points = []
        self.is_braking = False
        self.original_desired_velocity = self.desired_velocity

        self.target_index = 0
        self.target = self.target_path[self.target_index]
        self.quad = None

        self.initialize()

        self.current_max_repulsion = 160.0

        # Make sure this pedestrian is in the group.
        group.add_pedestrian(self)
        self.max_repulsive_force = group.world.turbulence_max_repulsion

        # Create a measurement history object to be filled on 'update'.
        self.measurements = []

    def initialize(self):
        # Start with a velocity equal to the desired velocity.
        self.desired_direction = self.get_desired_direction()
        velocity = self.desired_direction * self.desired_velocity
        self.velocity = np.array([velocity[0],  velocity[1]])

        self.next_velocity = self.velocity
        self.next_position = self.position
        self.speed = np.sqrt(self.velocity[0]**2 + self.velocity[1]**2)
        self.next_speed = self.speed

    def add_measurement(self, category, name, value):
        """ Add a measurement for this time step to this pedestrian.

        Args:
            category: category of measurement
            name: name of measurement
            value: value of measurement
        """
        # if category != 'self':
        #     return

        if category not in self.measurements[-1]:
            self.measurements[-1][category] = dict()
        self.measurements[-1][category][name] = value

    def get_measurement(self, category, name, time=-1):
        """ Get a measurement for a time step of this pedestrian.

        Args:
            category: category of measurement
            name: name of measurement
            time: array offset to get measurement from (default last)
        """
        if time is not -1 and time not in self.measurements:
            return False
        return self.measurements[time][category][name]

    def set_ornstein_uhlenbeck_process(self, mean, theta, sigma, process):
        """ Enable the Ornstein-Uhlenbeck process for deviating desired
        direction.

        The desired direction of the pedestrian will emulate brownian motion,
        but will gravitate towards the target.

        Args:
            mean: mean angle offset, usually zero
            theta: scaling factor of difference with mean
            sigma: scaling factor of random variation
        """
        if process == 'angle':
            self.angle_ou_process = (mean, theta, sigma)
        elif process == 'velocity':
            self.velocity_ou_process = (mean, theta, sigma)

    def step(self, step_size, obstacles):
        """ Calculate the position and velocity at next timestep.

        The new values are stored in the next_position and next_velocity
        attributes of the pedestrian. These are not immediately updated to
        avoid an order in which pedestrians are considered. Call the update
        function after step to update the position and velocity.

        Args:
            step_size: size of step, or time (dt) over which is propagated.
            pedestrians: list of pedestrians in system
            obstacles: list of obstacles in system
        """

        if len(self.target_path) == 0:
            self.next_velocity = np.array([0.0, 0.0])
            self.next_speed = 0.0
            return

        braking_chance = self.group.world.braking_chance
        if braking_chance > 0 and np.random.random() < braking_chance:
            # print("{}: Braking {}".format(self.group.world.time, self.id))
            self.desired_velocity = 0.0
            self.is_braking = True

        self.measurements.append({})
        self.add_measurement('self', 'time', self.group.world.time)

        # Calculate the new velocity and position using Social Force
        # Propagation.
        position, velocity = self.calculate_position_and_velocity(
            step_size, obstacles)

        # In case of a continuous domain, check if the pedestrian has
        # passed the boundaries. If so, move it.
        if self.group.world.continuous_domain:
            # Make a copy for future reference
            copy = np.array(position)
            position[0] = position[0] % self.group.world.width
            position[1] = position[1] % self.group.world.height

        # Update own position and velocity.
        self.next_position = position
        self.next_velocity = velocity

        # Update barrier counts.
        for barrier in self.group.world.barriers:
            barrier.check_if_passed(self)

        self.next_speed = np.sqrt(length_squared(self.next_velocity))

        # Add position, velocity and speed to history.
        self.add_measurement('self', 'position', self.next_position)
        self.add_measurement('self', 'velocity', self.next_velocity)
        self.add_measurement('self', 'speed', self.next_speed)

    def calculate_position_and_velocity(self, step_size, obstacles):
        """ Calculate the next position and velocity if this pedestrian.

        Args:
            step_size: size of step, or time (dt) over which is propagated.
            obstacles: list of obstacles in system

        Returns:
            np.array of size 2 containing new position
            np.array of size 2 containing new velocity
        """
        force = self.calculate_force(obstacles)

        # Calculate the new velocity
        velocity_new = self.velocity + step_size * force

        # Adjust new velocity if it is above maximum_velocity
        maximum_velocity = self.maximum_velocity
        if length_squared(velocity_new) > maximum_velocity**2:
            factor = np.sqrt((velocity_new[0]**2 + velocity_new[1]**2) /
                             maximum_velocity**2)
            velocity_new = velocity_new / factor

        self_position = np.array(self.position)

        position_new = self_position + step_size * velocity_new

        return position_new, velocity_new

    def goal_obstructed(self, goal, factor=1.0):
        """ Check whether the path to a goal is obstructed by obstacles. It does so by taking
        three points at consistent angles and checking if their line of sight is obstructed."""
        pos = np.array(self.position)
        if isinstance(goal, Area):
            goal = goal.get_closest_point(pos)

        goal_vec = goal - pos
        if length_squared(goal_vec) < 0.001:
            return False

        positions_checked = [pos + factor * self.radius * np.array([np.cos(angle), np.sin(angle)])
                             for angle in [0, 2.0 * np.pi / 3, 4.0 * np.pi / 3]]

        for obstacle in self.group.world.obstacles:
            for position in positions_checked:
                if obstacle.intersects(position, goal) is not None:
                    return True

        return False

    def update(self):
        """ Update the target_path and characteristics of this pedestrian. """
        if not self.quad.inside(self.next_position):
            self.group.world.quadtree.remove(self)
            try:
                self.group.world.quadtree.remove(self)
            except KeyError:
                print(self.position)
                print(self.next_position)
                print(self.quad.length)
                print(self.quad.xmin)
                print(self.quad.ymin)
                print(self.group.world.quadtree.length)
                raise

        # Determine whether braking should stop.
        if self.is_braking and (self.speed != self.next_speed and self.speed / self.next_speed < 1.5):
            self.is_braking = False
            self.desired_velocity = self.original_desired_velocity

        # Update position, velocity and speed.
        self.position = self.next_position
        self.velocity = self.next_velocity
        self.speed = self.next_speed

        # Updated desired velocity if Ornstein Uhlenbeck processes are enabled.
        if self.angle_ou_process is not False:
            # mean, theta, sigma = self.ornstein_uhlenbeck

            mean, theta, sigma = self.angle_ou_process

            angle = (theta * (mean - self.desired_offset_angle) *
                     self.group.world.step_size + sigma *
                     np.random.normal())
            self.desired_offset_angle += angle

        if self.velocity_ou_process is not False:
            # mean, theta, sigma = self.ornstein_uhlenbeck

            mean, theta, sigma = self.velocity_ou_process

            diff = (theta * (mean - self.desired_velocity_offset) *
                     self.group.world.step_size + sigma *
                     np.random.normal())
            self.desired_velocity_offset += diff

        # Make sure the pedestrian is inside the quadtree.
        if not self.quad:
            self.group.world.quadtree.add(self)

        # If the target index is out of range, we have reached our destination.
        if len(self.target_path) == self.target_index:
            return

        # First check if the current target is not obstructed. If it is, work
        # back through the target path to find the closest previous target that
        # is unobstructed.
        while True:
            obstructed = self.goal_obstructed(self.target)

            if obstructed:
                if self.target_index == 0:
                    # print "Error ({}): path obstructed.".format(self.id)
                    break
                else:
                    self.target_index -= 1
                    self.target = self.target_path[self.target_index]
            else:
                break

        # Find the next target that is not obstructed.
        if len(self.target_path) - self.target_index > 1:
            # Look for another target that is not obstructed from view.
            obstructed = False
            while not obstructed and len(self.target_path) - self.target_index > 1:
                next_target = self.target_path[self.target_index + 1]
                obstructed = self.goal_obstructed(next_target, factor=1.1)

                if not obstructed:
                    self.target_index += 1
                    self.target = self.target_path[self.target_index]

        self.desired_direction = self.get_desired_direction()

        # If there is only one target and it is within the threshold range,
        # remove it from this passenger.
        threshold = self.group.world.target_distance_threshold
        if len(self.target_path) - self.target_index == 1:
            if self.distance_to_target() < threshold:
                self.target_index += 1
                self.target = None

        # if len(self.target_path) > self.target_index:
        #     target = self.target_path[self.target_index]
        #     self.target = target

    def get_desired_direction(self):
        """ Finds and returns the desired direction of this pedestrian. """
        target = self.target

        # If the target is an area, find the closest point.
        if isinstance(target, Area):
            target = target.get_closest_point(self.position)

        # Calculate the desired direction
        desired_dir = target - self.position

        # If the target equals position, return a zero vector
        if length_squared(desired_dir) < 0.001:
            # print "Warning: target equals position"
            return desired_dir

        # Add a small angle to the desired direction.
        if self.desired_offset_angle != 0.0:
            # print self.desired_offset_angle
            c = np.cos(self.desired_offset_angle)
            s = np.sin(self.desired_offset_angle)
            R = np.matrix([[c, -s],  [s, c]])
            res = R.dot(desired_dir)
            desired_dir = np.array([res[0, 0], res[0, 1]])

        return desired_dir / np.linalg.norm(desired_dir)

    def arrived(self):
        """ Returns whether the pedestrian has arrived at its target. """
        if self.target_index == len(self.target_path):
            return True

        if self.target_index + 1 < len(self.target_path):
            return False

        if isinstance(self.target, Area):
            return self.group.target_area.in_area(self.position)

        if self.distance_to_target() < self.group.world.target_distance_threshold:
            return True

        return False

    def distance_to_target(self):
        """ Returns the distance to the current target. """
        if self.target_index == len(self.target_path):
            return 0.0

        target = self.target

        if isinstance(target, Area):
            target = target.get_closest_point(self.position)

        return np.sqrt(length_squared(self.position - target))

    def set_desired_velocity(self, velocity):
        """ Set the desired velocity of this pedestrian. """
        self.desired_velocity = velocity

    def calculate_force(self, obstacles):
        """ Calculates the sum of attractive and repulsive forces.

        Args:
            pedestrians: list of pedestrians in system
            obstacles: list of obstacles in system

        Returns:
            np.array: sum of forces
        """

        # Get the pedestrians in the current neighbourhood.
        world = self.group.world
        tree = world.quadtree
        threshold = world.interactive_distance_threshold
        pedestrians = tree.get_pedestrians_in_range(self.position, threshold)

        # If we are currently in a continuous domain, we may need to find
        # neighbours on the other side of the domain.
        if world.continuous_domain:

            # For an x near the threshold
            if self.position[0] - threshold < 0:
                new_position = np.array(self.position)
                new_position[0] = world.width
                new_threshold = np.sqrt(threshold**2 - self.position[0]**2)
                pedestrians = pedestrians.union(
                    tree.get_pedestrians_in_range(new_position, new_threshold)
                )

            if self.position[0] + threshold > world.width:
                new_position = np.array(self.position)
                new_position[0] = 0
                new_threshold = np.sqrt(threshold**2 - (
                    world.width - self.position[0])**2)
                pedestrians = pedestrians.union(
                    tree.get_pedestrians_in_range(new_position, new_threshold)
                )

            # For a y near the threshold
            if self.position[1] - threshold < 0:
                new_position = np.array(self.position)
                new_position[1] = world.height
                new_threshold = np.sqrt(threshold**2 - self.position[1]**2)
                pedestrians = pedestrians.union(
                    tree.get_pedestrians_in_range(new_position, new_threshold)
                )

            if self.position[1] + threshold > world.height:
                new_position = np.array(self.position)
                new_position[1] = 0
                new_threshold = np.sqrt(threshold**2 - (
                    world.height - self.position[1])**2)
                pedestrians = pedestrians.union(
                    tree.get_pedestrians_in_range(new_position, new_threshold)
                )

        # Calculate the forces and return the sum of forces.
        attractive = self.calculate_attractive_force(pedestrians)
        ped_repulsive, ped_physical = self.calculate_pedestrian_repulsive_force(pedestrians)
        ob_repulsive = self.calculate_obstacle_repulsive_force(obstacles)

        # Ignore other pedestrians if braking.
        if self.is_braking:
            print(attractive, ped_repulsive, ob_repulsive)
            ped_repulsive = np.array([0.0, 0.0])

        total_force = attractive + self.group.repulsion_weight * (
            ped_repulsive + ob_repulsive + ped_physical)

        random_force = np.zeros(2)
        if world.velocity_variance_factor > 0.0:
            stdev = world.velocity_variance_factor * world.step_size
            random_force = np.random.normal(0.0, stdev, size=2)

        # Check whether the unit is going backwards
        target = self.target
        if isinstance(target, Area):
            target = target.get_closest_point(self.position)
        angle_between_force_and_target = angle_between(total_force, target - self.position)
        angle_between_velocity_and_target = angle_between(self.velocity, target - self.position)

        self.add_measurement('forces', 'force_angle', angle_between_force_and_target)
        self.add_measurement('forces', 'velocity_angle', angle_between_velocity_and_target)
        self.add_measurement('forces', 'attractive', attractive)
        self.add_measurement('forces', 'pedestrian_repulsive', ped_repulsive)
        self.add_measurement('forces', 'obstacle_repulsive', ob_repulsive)

        return total_force + random_force

    def calculate_attractive_force(self, pedestrians):
        """ Calculates the attractive force towards the next target.

        Returns:
            np.array: attractive force towards target.
        """

        desired_dir = self.desired_direction
        velocity_factor = self.group.world.desired_velocity_importance
        # braking_chance = self.group.world.braking_chance
        preferred_velocity = np.array([0.0, 0.0])

        # Calculate average velocity in neighbourhood.
        average_velocity = np.array([0.0, 0.0])
        if velocity_factor < 1.0 and len(pedestrians):
            for p in pedestrians:
                average_velocity += p.velocity
            average_velocity /= len(pedestrians)
        else:
            velocity_factor = 1.0

        # print(self.relaxation_time)

        # There might be a chance the pedestrian randomly brakes.
        # In that case, set preferred_velocity to (0, 0).
        # if braking_chance > 0 and random.random() < braking_chance:
        #     pass
        # else:

        # Calculate the preferred velocity, which consists of a weighted
        # sum of the desired velocity towards target and the average
        # velocity.
        actual_desired_velocity = max(0.0, self.desired_velocity + self.desired_velocity_offset)
        preferred_velocity = ((velocity_factor * actual_desired_velocity * desired_dir) +
                              (1 - velocity_factor) * average_velocity)

        attractive_force = (- self.mass * (self.velocity -
                            preferred_velocity) / self.relaxation_time)

        return attractive_force

    def calculate_pedestrian_repulsive_force(self, pedestrians):
        """ Calculates the repulsive force with all others pedestrians.

        Args:
            pedestrians: list of pedestrians in system.

        Returns:
            np.array: sum of repulsive forces from all other pedestrians.
        """

        world = self.group.world
        p_position = []
        p_velocity = []
        p_radius = []

        for p in pedestrians:
            if p == self:
                continue

            p_position.append(p.position)
            p_velocity.append(p.radius)
            p_radius.append(p.radius)

        if len(p_position) == 0:
            self.add_measurement('forces', 'local_density', 0.0)
            self.add_measurement('forces', 'local_velocity_variance', 0.0)
            self.add_measurement('forces', 'repulsive_force', 0.0)
            self.add_measurement('forces', 'pushing_force', 0.0)
            return np.array([0.0, 0.0]), np.array([0.0, 0.0])

        force_args = []
        # force_args.append(world.turbulence_max_repulsion)
        force_args.append(self.max_repulsive_force)
        force_args.append(world.turbulence_lambda)
        force_args.append(world.turbulence_d0)
        force_args.append(world.turbulence_d1)
        force_args.append(float(world.body_force_constant))
        force_args.append(float(world.friction_force_constant))

        smoothing_squared = world.smoothing_parameter**2
        smoothing_factor = 1.0 / (np.pi * smoothing_squared)
        force_args.append(smoothing_squared)
        force_args.append(smoothing_factor)

        labda_factor = 1.0
        if self.group.world.scale_lambda:
            velocity_x_component = np.dot(
                np.dot(self.velocity, self.desired_direction) / np.dot(self.desired_direction, self.desired_direction),
                self.desired_direction
            )[0]

            labda_factor = min(1.0, max(0.0, velocity_x_component / self.desired_velocity))

        force = calculate_pedestrian_repulsive_force(
            world.interactive_distance_threshold, self.position, self.velocity,
            self.radius, self.speed, labda_factor, p_position, p_velocity, p_radius,
            world.height, world.width, world.continuous_domain,
            world.ignore_pedestrians_behind, self.desired_direction,
            force_args, world.turbulence_exponent)

        # print(force)
        self.add_measurement('forces', 'local_density', force[4])
        self.add_measurement('forces', 'local_velocity_variance',
                             force[5])
        self.add_measurement('forces', 'repulsive_force', force[6])
        self.add_measurement('forces', 'pushing_force', force[7])

        return np.array([force[0], force[1]]), np.array([force[2], force[3]])

    def calculate_pedestrian_repulsive_force_old(self, pedestrians):
        """ Calculates the repulsive force with all others pedestrians.
        This function is deprecated.

        Args:
            pedestrians: list of pedestrians in system.

        Returns:
            np.array: sum of repulsive forces from all other pedestrians.
        """
        world = self.group.world

        # The following parameters were inspired by the Java SFM implementation
        repulsion_coefficient = world.repulsion_coefficient
        falloff_length = world.falloff_length
        body_force_constant = world.body_force_constant
        friction_force_constant = world.friction_force_constant

        distance_threshold = self.group.world.interactive_distance_threshold
        neighbourhood_distances = []
        pushing_forces = []
        friction_forces = []

        force = np.zeros(2)
        local_density = 0.0
        local_velocity_variance = 0.0

        # Loop through all pedestrians.
        for p in pedestrians:
            # Skip if self.
            if p == self:
                continue

            p_position = np.array(p.position)

            # Calculate the distance.
            position = self.position
            difference = p_position - position

            # In case of a continuous domain, we should check if the 'wrapped'
            # distance is closer.
            if self.group.world.continuous_domain:
                if difference[0] > 0.5 * self.group.world.width:
                    difference[0] = difference[0] - self.group.world.width
                    p_position[0] -= self.group.world.width
                elif difference[0] < - 0.5 * self.group.world.width:
                    difference[0] = difference[0] + self.group.world.width
                    p_position[0] += self.group.world.width

                if difference[1] > 0.5 * self.group.world.height:
                    difference[1] = difference[1] - self.group.world.height
                    p_position[1] -= self.group.world.height
                elif difference[1] < - 0.5 * self.group.world.height:
                    difference[1] = difference[1] + self.group.world.height
                    p_position[1] += self.group.world.height

            distance_squared = difference[0]**2 + difference[1]**2

            # Skip if the pedestrian is too far away. This saves a significant
            # amount of time in large groups.
            if distance_squared > distance_threshold:
                continue

            # In some cases, we want to ignore pedestrians that are 'behind' us
            if self.group.world.ignore_pedestrians_behind:
                # Calculate how far 'behind' the person is.
                desired_dir = self.desired_direction
                front_factor = (desired_dir[0] * difference[0] +
                                desired_dir[1] * difference[1])
                # print "{} -- {}: {}".format(self.id, p.id, front_factor)
                # Check if the distance exceeds the sum of radi.
                if front_factor < - self.radius - p.radius:
                    continue

            distance = np.sqrt(distance_squared)
            neighbourhood_distances.append(distance)

            # Agent overlap is positive if two agents 'overlap' in space.
            agent_overlap = self.radius + p.radius - distance

            # Unit vector of the difference
            difference_direction = difference / distance

            # Find normal and tangential of difference
            normal = (position - p_position) / distance
            # normal[1] = -normal[1]
            tangential = np.array([-normal[1], normal[0]])

            # Method 1: Original
            #####################
            if not world.turbulence:
                social_repulsion_force = repulsion_coefficient * np.exp(
                    agent_overlap / falloff_length)

            # Method 2: Turbulent force
            ############################
            else:
                max_repulsive_force = world.turbulence_max_repulsion
                labda = world.turbulence_lambda
                k = world.turbulence_exponent
                D_zero = world.turbulence_d0
                D_one = world.turbulence_d1

                try:
                    factor = max(distance, 0.15)
                    cos_angle = self.desired_direction * difference_direction
                    omega = labda + (1 - labda) * (1 + cos_angle) / 2
                    social_repulsion_force = (max_repulsive_force * omega *
                                              np.exp(- factor / D_zero +
                                                     (D_one / factor)**k))
                except:
                    print(distance, cos_angle, omega)
                    raise

            pushing_force = 0
            friction_force = np.array([0, 0])

            if agent_overlap > 0:
                # Find delta, which is a factor for friction force.
                delta = (p.velocity - self.velocity) * tangential

                pushing_force = body_force_constant * agent_overlap
                friction_force = (friction_force_constant * agent_overlap *
                                  delta * tangential)

            # Sum the forces and add to total force.
            pedestrian_force = ((social_repulsion_force + pushing_force) *
                                normal + friction_force)

            pushing_forces.append(pushing_force)
            friction_forces.append(np.sqrt(friction_force[0]**2 +
                                   friction_force[1]**2))

            force += pedestrian_force
            pressure = smoothing_factor * np.exp(-distance_squared /
                                                 smoothing_squared)

            local_density += pressure
            local_velocity_variance += self.speed * pressure

        if local_density != 0:
            local_velocity_variance /= local_density

        # self.add_measurement('neighbourhood', 'distances',
        #                      neighbourhood_distances)
        # self.add_measurement('neighbourhood', 'num_neighbours',
        #                      len(neighbourhood_distances))
        # self.add_measurement('forces', 'pushing', pushing_forces)
        # self.add_measurement('forces', 'friction', friction_forces)
        self.add_measurement('forces', 'local_density', local_density)
        self.add_measurement('forces', 'local_velocity_variance',
                             local_velocity_variance)

        return force

    def calculate_obstacle_repulsive_force(self, obstacles):
        """ Calculates the repulsive force with the closest obstacle.

        Args:
            obstacles: list of obstacles in the system.

        Returns:
            np.array: repulsive force from closest obstacle.
        """

        # The following parameters were inspired by the Java SFM implementation
        world = self.group.world
        repulsion_coefficient = world.repulsion_coefficient
        falloff_length = world.falloff_length
        body_force_constant = world.body_force_constant
        friction_force_constant = world.friction_force_constant
        desired_dir = self.get_desired_direction()

        self.closest_obstacle_points = []

        distance_threshold = 2.0

        force = np.zeros(2)

        # Loop through all obstacles.
        for o in obstacles:

            # Calculate the distance.
            position = self.position
            obstacle_position, normal = o.closest_point(self.position,
                                                        distance_threshold)
            if obstacle_position is None:
                continue

            self.closest_obstacle_points.append(obstacle_position)

            difference = obstacle_position - position

            distance = np.sqrt(difference[0]**2 + difference[1]**2)

            # Agent overlap is positive if two agents 'overlap' in space.
            agent_overlap = self.radius - distance

            # Unit vector of the difference
            difference_direction = difference / distance

            # Find tangential
            tangential = np.array([-normal[1], normal[0]])

            # Get angle
            # cos_angle = desired_dir * difference_direction
            # omega = world.turbulence_lambda + (1 - world.turbulence_lambda) * (1 + cos_angle) / 2
            # obstacle_repulsion_force = repulsion_coefficient * omega * np.exp(
            #     agent_overlap / falloff_length)
            obstacle_repulsion_force = repulsion_coefficient * np.exp(
                agent_overlap / falloff_length)

            pushing_force = 0
            friction_force = 0

            if agent_overlap > 0:
                # Find delta, which is a factor for friction force.
                delta = self.velocity * tangential

                pushing_force = body_force_constant * agent_overlap
                friction_force = (friction_force_constant * agent_overlap *
                                  delta * tangential)

            # Sum the forces and add to total force.
            obstacle_force = ((obstacle_repulsion_force + pushing_force) *
                              normal + friction_force)

            force += obstacle_force

        return force

    def plot(self, ax, color, add_quiver=False, plot_target=False):
        """ Plot this pedestrian on a figure.

        Args:
            ax: the pyplot axis on which to draw the pedestrian
            add_quiver: whether to add a quiver or not
            kwargs: pyplot keyword arguments
        """

        # red_blue = cm = plt.get_cmap('RdBu')
        # c_norm = matplotlib.colors.SymLogNorm(linthresh=0.03, linscale=0.03,
        #                                       vmin=-1.0, vmax=1.0)
        # scalarmap = matplotlib.cm.ScalarMappable(norm=c_norm, cmap=red_blue)
        # core_color = scalarmap.to_rgba(self.speed - self.desired_velocity)

        c = 'white'
        # if self.speed < 0.2:
        #     c = 'red'

        ax.add_artist(Circle(xy=(self.position), radius=0.5 * self.diameter,
                             facecolor=c, edgecolor=color, fill=True))

        mirrorred_positions = []

        if self.position[0] < self.radius:
            mirrorred_positions.append(self.position + np.array([self.group.world.width, 0]))
        if self.position[0] > self.group.world.width - self.radius:
            mirrorred_positions.append(self.position - np.array([self.group.world.width, 0]))

        for position in mirrorred_positions:
            ax.add_artist(Circle(xy=position, radius=0.5 * self.diameter,
                                 facecolor=c, edgecolor=color, fill=True))

        if add_quiver:
            ax.quiver(self.position[0], self.position[1],
                      self.velocity[0], self.velocity[1], angles='xy',
                      scale_units='xy', color=color)
        if plot_target:
            target = self.target
            if isinstance(target, Area):
                target = target.get_closest_point(self.position)
            ax.scatter(target[0], target[1])
            ax.plot([self.position[0], target[0]], [self.position[1], target[1]], alpha=0.3)
            for o in self.closest_obstacle_points:
                ax.plot([self.position[0], o[0]], [self.position[1], o[1]])


# Two pointers
def removeDuplicates(nums):
    """
    Two pointers, with many conditions
    Time: O(n)
    Space: O(n)
    """
    # the slow pointer: stop_ind
    stop_ind = 0  # [0, stop_ind] contains the results
    count = 1  # number of (consecutive, since the list is sorted) occurrence of nums[stop_ind] in [0, stop_ind]

    for i in range(len(nums)):
        # check if index is valid
        if stop_ind + 1 >= len(nums):
            break

        # the following condition is True for two cases:
        # 1) nums[stop_ind - 1] and nums[stop_ind] are the same, but nums[i] is not, update
        # in 1), nums[stop_ind + 1] is the same as nums[stop_ind] and needs to be overwritten by nums[i]
        # 2) nums[stop_ind - 1], nums[stop_ind] and nums[i] are all the same, do not update
        # in 2), nums[stop_ind + 1] is less than nums[stop_ind] (since the latter has been overwritten)
        if nums[i] > nums[stop_ind + 1] and count == 2:
            if not nums[i] == nums[stop_ind]:
                nums[stop_ind + 1] = nums[i]
                count = 1
                stop_ind += 1

        # if the following condition is True, we will overwrite nums[stop_ind + 1]
        elif nums[i] > nums[stop_ind + 1] and count < 2:
            nums[stop_ind + 1] = nums[i]
            # the following condition is True then we are still updating the same pair
            if nums[stop_ind + 1] == nums[stop_ind]:
                count += 1
            # otherwise, it means we are starting with a new pair
            else:
                count = 1
            stop_ind += 1

        # this part is only reached if nums[i] == nums[stop_ind + 1]
        # if the following statement is True, then no overwriting is needed
        elif nums[stop_ind + 1] > nums[stop_ind]:
            count = 1
            stop_ind += 1

        # if the following statement is True, then we are in the same pair, no need for overwriting
        elif nums[stop_ind + 1] == nums[stop_ind] and count < 2:
            count += 1
            stop_ind += 1

        # if the following statement is True, then we need to overwrite nums[stop_ind + 1]
        elif nums[stop_ind + 1] == nums[stop_ind] and count == 2:
            continue

    return stop_ind + 1, nums[:stop_ind + 1]

def removeDuplicates_pop(nums):
    """
    Popping
    Time: O(n^2) worst case: all numbers in nums are the same
    Space: O(1)
    """
    count = 1
    i = 1
    while True:
        # stop the loop
        if i >= len(nums):
            break

        # still in a pair
        if nums[i] == nums[i - 1] and count < 2:
            count += 1
            i += 1

        # duplicate detected, remove
        elif nums[i] == nums[i - 1] and count == 2:
            # pop time complexity: O(n)
            nums.pop(i)

        # start a new pair
        elif nums[i] > nums[i - 1]:
            count = 1
            i += 1

    return len(nums), nums

def removeDuplicates_two_pointers(nums):
    """
    Another way of two pointers
    Time: O(n)
    Space: O(n)
    """
    stop_ind_next = 1  # here stop_ind_next indicates the next element of the processed array
    count = 1  # count has to start from 1 since we are starting with nums[0]
    # i should start the loop at the same position as stop_ind_next
    for i in range(1, len(nums)):
        # now we have encountered more an element at stop_ind_next that needs to be removed
        if count >= 2:
            # the following statement will be True once i proceed to a different element than nums[stop_ind_next]
            # all nums[stop_ind_next] to nums[i] will be the same
            if nums[i] != nums[i - 1]:
                # copy (overwrite) nums[stop_ind_next] with the next different element
                nums[stop_ind_next] = nums[i]
                stop_ind_next += 1
                # count is now 1 again
                count = 1
        # we can add one more element that is the same as nums[stop_ind_next - 1]
        else:
            nums[stop_ind_next] = nums[i]
            # if nums[stop_ind_next] is not the same, reset count
            if nums[stop_ind_next] != nums[stop_ind_next - 1]:
                count = 1
            else:
                count += 1
            stop_ind_next += 1

    return stop_ind_next, nums[:stop_ind_next]

# test = [1, 2, 2]
# test = [1, 1, 1, 2, 2, 3]
# test = [0, 0, 1, 1, 1, 1, 2, 3, 3]
# test = [1, 1, 1, 1, 1, 2, 2, 2, 4]
test = [0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4]
print(removeDuplicates_two_pointers(test))


import os

from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch.actions import DeclareLaunchArgument

def generate_launch_description():
    pkg_rover_localization = get_package_share_directory("rover_localization")
    use_sim_time = LaunchConfiguration("use_sim_time")

    use_sim_time_cmd = DeclareLaunchArgument(
        "use_sim_time",
        default_value="True",
        description="Use simulation (Gazebo) clock if True")

    ekf_cmd = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(pkg_rover_localization,
                        "launch", "ekf.launch.py")
            ), launch_arguments = {"use_sim_time": use_sim_time}.items()
    )

    ld = LaunchDescription()
    ld.add_action(use_sim_time_cmd)
    ld.add_action(ekf_cmd)

    return ld


# -*- encoding: utf-8 -*-
'''
@project :   LeetCode
@File    :   canThreePartsEqualSum.py
@Contact :   9824373@qq.com
@Desc    :
            给你一个整数数组 A，只有可以将其划分为三个和相等的非空部分时才返回 true，否则返回 false。

            形式上，如果可以找出索引 i+1 < j 且满足 (A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length - 1]) 就可以将数组三等分。

            示例 1：

            输出：[0,2,1,-6,6,-7,9,1,2,0,1]
            输出：true
            解释：0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
            示例 2：

            输入：[0,2,1,-6,6,7,9,-1,2,0,1]
            输出：false
            示例 3：

            输入：[3,3,6,5,-2,2,5,1,-9,4]
            输出：true
            解释：3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4

            提示：

            3 <= A.length <= 50000
            -10^4 <= A[i] <= 10^4

            来源：力扣（LeetCode）
            链接：https://leetcode-cn.com/problems/partition-array-into-three-parts-with-equal-sum

@Modify Time                @Author     @Version    @Desciption
------------                -------     --------    -----------
2020-03-11     zhan        1.0         None
'''
from typing import List

class Solution:
    def canThreePartsEqualSum(self, A: List[int]) -> bool:
        if len(A) <= 2: return False
        total = sum(A)
        if total % 3 != 0: return False

        tmpSum = 0
        iflag = 0

        for i, val in enumerate(A):
            tmpSum += val
            if tmpSum == total/3:
                tmpSum = 0
                iflag += 1

            if iflag == 3:
                break

        if iflag == 3: return True
        else: return False

if __name__ == '__main__':
    A = [0, 2, 1, -6, 6, -7, 9, 1, 2, 0, 1]
    A = [0,2,1,-6,6,7,9,-1,2,0,1]
    A = [3,3,6,5,-2,2,5,1,-9,4]
    ans = Solution().canThreePartsEqualSum(A)
    print(ans)


import sys
from contextlib import contextmanager
import math
import unittest
from test_common import *
import task3

class TestTask3(TestCase):
  def test_statistics(self):
    table = task3.HashTable(1024, 1)

    # First Test Statistics
    with self.vis("testing statistics"):
      for key in ["abcdef", "defabc"]:
        table[key] = 1
      stats = table.statistics()

    # Second Test Statistics
    with self.vis():
      for key in ["acbedf"]:
        table[key] = 1
      stats = table.statistics()
      self.assertEqual(stats, (2, 3, 2, 0), "incorrect statistics")

    self.assertTrue(self.check_okay("statistics"))

  def test_load_statistics(self):

    # First Test case
    with self.vis("reporting words"):
      (w, _, _, _, _, _) = self.with_deadline(1, task3.load_dictionary_statistics, (1, 1024, "words_perm.txt", 10))
      self.assertEqual(w, 5, "incorrect word count")

    # Second Test case
    with self.vis("reporting words"):
      (w, _, _, _, _, _) = self.with_deadline(1, task3.load_dictionary_statistics, (1, 1024, "words_empty.txt", 10))
      self.assertEqual(w, 11, "incorrect word count")

    self.assertTrue(self.check_okay("load_statistics"))

  def test_load_2(self):
    " Here, another file is opended and there are 5 lines. "
    with self.vis():
      table = task3.HashTable()
      task3.load_dictionary(table, "words_perm.txt", 10)
      self.assertEqual(count_nonempty_buckets(table), 5)

    with self.vis():
      table = task3.HashTable()
      task3.load_dictionary(table, "words_empty.txt", 10)
      self.assertEqual(count_nonempty_buckets(table), 11)
    self.assertTrue(self.check_okay("load_dictionary"))

  def test_load_timeout(self):
    "Load without time will use the default value of the time out"
    "Default value of the time out is 120 (2 Seconds)"
    with self.vis("load without max_time"):
      table = task3.HashTable()
      task3.load_dictionary(table, "words_simple.txt")

    with self.vis("failed to apply timeout"):
      table = task3.HashTable(100000, 1)
      with self.assertRaises(Exception, msg = "reading too many words should time out."):
          self.with_deadline(3, task3.load_dictionary, (table, "english_small.txt", 1))

    # Check with small 500, size
    with self.vis("failed to apply timeout"):
      table = task3.HashTable(500, 1)
      with self.assertRaises(Exception, msg = "reading too many words should time out."):
          self.with_deadline(3, task3.load_dictionary, (table, "english_small.txt", 1))

  # Test load time function
  def test_load_time(self):
    # Test for the words_simple
    (words, time, _, _, _, _) = self.with_deadline(1, task3.load_dictionary_statistics, (31, 100, "words_simple.txt", 10))
    self.assertEqual(words, 6)
    # Test for the words_empty
    (words, time, _, _, _, _) = self.with_deadline(1, task3.load_dictionary_statistics, (31, 100, "words_empty.txt", 10))
    self.assertEqual(words, 11)

  # Test test_table_load_dictionary_time
  def test_table_load_dictionary_time(self):
    task3.table_load_dictionary_statistics(5)
    self.assertTrue(self.check_okay("table_load_dictionary_time"))
if __name__ == '__main__':
  unittest.main()


import datetime

import urllib, httplib, urlparse
import utils

class SimpleRestApiClient:
    """
    Create rest client for simplifying http/https requests
    """

    def __init__(self, base_url, common_url_params = {}):
        """
        * base_url - usually endpoint of rest api http://example/api/v2
        * common_url_params - url params which will be mixed into every request. For example api key
        """
        self.base_url = base_url
        self.common_url_params = common_url_params

    def GET(self, action_url, url_params = {}):
        """
        Make GET request
        """
        url = self.base_url + "/" + action_url
        parsed_url = urlparse.urlparse(url)
        if parsed_url.scheme == 'https':
            connection = httplib.HTTPSConnection(parsed_url.hostname)
        else:
            connection = httplib.HTTPConnection(parsed_url.hostname)
        get_path = parsed_url.path
        query = urllib.urlencode(utils.merge_dicts(self.common_url_params, url_params))
        if query:
            get_path += "?" + query
        connection.request('GET', get_path)
        response = connection.getresponse()
        response_data = response.read()
        connection.close()
        return response_data

    def POST(self, action_url, url_params=None, post_data=None):
        """
        Make GET request
        """
        raise NotImplementedError("Not implemented yet")

def merge_dicts(dict1, dict2):
    """
    Merge two dicts into 1
    """
    z = dict1.copy()
    z.update(dict2)
    return z

def calculate_age(born_str, today=None):
    """
    Calculate age by date of birth. Format yyyy-mm-dd. Sometimes freebase return only year
    """
    if not born_str:
        return None
    if not today:
        today = datetime.date.today()
    parts = born_str.split('-')
    if len(parts) == 3:
        fmt = '%Y-%m-%d'
    elif len(parts) == 2:
        fmt = '%Y-%m'
    else:
        fmt = '%Y'
    born = datetime.datetime.strptime(born_str, fmt)

    return today.year - born.year - ((today.month, today.day) < (born.month, born.day))

def calc_average(total_age, cast_number, none_number):
    """
    Calculate age average for film
    """
    average = 0
    if (cast_number - none_number) != 0:
        average = total_age / (cast_number - none_number)
    return float(average)

def calc_accuracy(cast_number, none_number):
    accuracy = 100*(cast_number - none_number)/cast_number
    return float(accuracy)


import sirs
from settings import HOST

import json
import os

DATA_DIRECTORY = 'data'

api = sirs.API(HOST)
os.makedirs(DATA_DIRECTORY, exist_ok=True)

print('downloading data from %s' % api.url)
for name, table in api.tables.items():
    path = os.path.join(DATA_DIRECTORY, name + '.json')
    print(
        'writing contents of table %s (at %s) to file %s ... ' % (name, table.url, path),
        end='', flush=True
    )
    data = table.get()
    print('writing %d records ... ' % len(data), end='', flush=True)
    with open(path, 'w') as data_file:
        data_file.write(json.dumps(data, indent=2, sort_keys=True))
    print('done')


from train import *

frames = []
def save_frames(trajectory):
    global frames
    frames.append(tf_env.pyenv.envs[0].render(mode = "rgb_array"))

prev_lives = tf_env.pyenv.envs[0].ale.lives()
def reset_and_fire_on_life_lost(trajectory):
    global prev_lives
    lives = tf_env.pyenv.envs[0].ale.lives()
    if prev_lives != lives:
        tf_env.reset()
        tf_env.pyenv.envs[0].step(np.array(1))
        prev_lives = lives

watch_driver = DynamicStepDriver(
    tf_env,
    agent.policy,
    observers = [save_frames, reset_and_fire_on_life_lost, init.ShowProgress(1000)],
    num_steps = 1000)

final_time_step, final_policy_state = watch_driver.run()
image_path = os.path.join("Breakout.gif")
frame_images = [PIL.Image.fromarray(frame) for frame in frames[:150]]
frame_images[0].save(
    image_path, format = "GIF",
    append_images=frame_images[1:],
    save_all = True, duration = 30, loop = 0)