import usb1
import threading
import re

try:
	import queue
except ImportError:
	import Queue as queue

from octoprint.settings import settings
from octoprint.events import Events, eventManager

class FlashForgeError(Exception):
	def __init__(self, message, error=0):
		super(FlashForgeError, self).__init__(("{} ({})" if error else "{}").format(message, error))
		self.error = error

class FlashForge(object):
	BUFFER_SIZE = 512

	STATE_UNKNOWN = 0
	STATE_READY = 1
	STATE_BUILDING = 2
	STATE_SD_BUILDING = 3
	STATE_SD_PAUSED = 4
	STATE_HOMING = 5
	STATE_BUSY = 6
	STATE_WAIT_ON_TEMP = 7

	PRINTING_STATES = [STATE_BUILDING, STATE_SD_BUILDING, STATE_SD_PAUSED]

	regex_SDPrintProgress = re.compile(b"(?P<current>[0-9]+)/(?P<total>[0-9]+)")
	""" Regex matching SD print progress from M27. """
	regex_gcode = re.compile(b"^(N[0-9]+\s+)?(?P<gcode>[GM][0-9]+)(\s+(?P<payload>.+))?")
	""" Regex matching gcodes in write(). """
	regex_g1 = re.compile(
		b"G[01](?=.* X(?P<X>-?[0-9.]+))?(?=.* Y(?P<Y>-?[0-9.]+))?(?=.* Z(?P<Z>-?[0-9.]+))?(?=.* E(?P<E>-?[0-9.]+))?(?=.* F(?P<F>[0-9.]+))?")
	""" Regex matching move G1 commands for noG91 handling. """
	regex_M114position = re.compile(
		b"X:(?P<X>-?[0-9.]+) Y:(?P<Y>-?[0-9.]+) Z:(?P<Z>-?[0-9.]+) E0:(?P<E0>-?[0-9.]+)( E1:(?P<E1>-?[0-9.]+))?")
	""" Regex matching position values from M114 """

	def __init__(self, plugin, comm, usbcontext, portname, printer, read_timeout=10.0, write_timeout=10.0):
		import logging
		self._logger = logging.getLogger("octoprint.plugins.flashforge")
		self._logger.debug("__init__()")

		self._plugin = plugin
		self._comm = comm
		self._usbcontext = usbcontext
		self._handle = None
		self._portname = portname
		self._read_timeout = read_timeout
		self._write_timeout = write_timeout
		self._keep_alive_t = None
		self._keep_alive_enabled = False
		self._status_time = 0.0
		self._temp_time = 0.0
		self._temp_interval = 0.0
		self._autotemp_enabled = True
		self._is_autotemp = False
		self._incoming = queue.Queue()
		self._readlock = threading.Lock()
		self._writelock = threading.Lock()
		self._printerstate = self.STATE_UNKNOWN
		self._disconnect_event = False

		self._noG91 = False
		self._relative_pos = False
		self._pos = {"X": 0.0, "Y": 0.0, "Z": 0.0, "E0": 0.0, "E1": 0.0}
		self._extruder = "E0"

		self._usb_cmd_endpoint_in = 0
		self._usb_cmd_endpoint_out = 0
		self._usb_sd_endpoint_in = 0
		self._usb_sd_endpoint_out = 0

		for device in self._usbcontext.getDeviceIterator(skip_on_error=True):
			if printer["bus"] == device.getBusNumber() and printer["addr"] == device.getDeviceAddress():
				try:
					self._handle = device.open()
				except usb1.USBErrorAccess:
					eventManager().fire(Events.ERROR, {
						"error": "Found printer but there is a connection problem - check Terminal window for details.",
						"reason": "connection"})
					raise FlashForgeError("\r\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\r\n\r\n"
										  "Unable to connect to FlashForge printer - permission error.\r\n\r\n"
										  "If you are using OctoPi/Linux add permission to access this device by editing file:\r\n /etc/udev/rules.d/99-octoprint.rules\r\n\r\n"
										  "and adding the line:\r\n"
										  "SUBSYSTEM==\"usb\", ATTR{{idVendor}}==\"{:04x}\", MODE=\"0666\"\r\n\r\n"
										  "You can do this as follows:\r\n"
										  "1) Connect to your OctoPi/Octoprint device using ssh\r\n"
										  "2) Type the following to open a text editor:\r\n"
										  "sudo nano /etc/udev/rules.d/99-octoprint.rules\r\n"
										  "3) Add the following line:\r\n"
										  "SUBSYSTEM==\"usb\", ATTR{{idVendor}}==\"{:04x}\", MODE=\"0666\"\r\n"
										  "4) Save the file and close the editor\r\n"
										  "5) Verify the file permissions are set to \"rw-r--r--\" by typing:\r\n"
										  "ls -al /etc/udev/rules.d/99-octoprint.rules\r\n"
										  "6) Reboot your system for the rule to take effect.\r\n\r\n"
										  "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\r\n\r\n".format(printer["vid"], printer["vid"]))
				except usb1.USBError as usberror:
					raise FlashForgeError('Unable to connect to FlashForge printer - may already be in use', usberror)
				break

		if not self._handle:
			self._logger.debug("No FlashForge printer found")
			raise FlashForgeError('No FlashForge Printer found')

		try:
			self._handle.claimInterface(0)
		except usb1.USBError as usberror:
			raise FlashForgeError('Unable to connect to FlashForge printer - may already be in use', usberror)

		self._logger.debug("claimed USB interface")
		device = self._handle.getDevice()
		# look for an in and out endpoint pair:
		for configuration in device.iterConfigurations():
			for interface in configuration:
				for setting in interface:
					self._logger.debug(" setting number: 0x{:02x}, class: 0x{:02x}, subclass: 0x{:02x}, protocol: 0x{:02x}, #endpoints: {}".format(
						setting.getNumber(), setting.getClass(), setting.getSubClass(), setting.getProtocol(), setting.getNumEndpoints()))
					endpoint_in = 0
					endpoint_out = 0
					for endpoint in setting:
						self._logger.debug("  found endpoint type {} at address 0x{:02x}, max packet size {}".
							format(usb1.libusb1.libusb_transfer_type.get(endpoint.getAttributes()),
							endpoint.getAddress(),
							endpoint.getMaxPacketSize()))
						if usb1.libusb1.libusb_transfer_type.get(endpoint.getAttributes()) == 'LIBUSB_TRANSFER_TYPE_BULK':
							address = endpoint.getAddress()
							if address & usb1.ENDPOINT_IN:
								endpoint_in = address
							else:
								endpoint_out = address
							if endpoint_in and endpoint_out:
								# we have a pair of endpoints, assign them as needed
								# assume first pair is for commands, second for SD upload
								if not self._usb_cmd_endpoint_out:
									self._usb_cmd_endpoint_in = endpoint_in
									self._usb_cmd_endpoint_out = endpoint_out
									endpoint_in = endpoint_out = 0
								elif not self._usb_sd_endpoint_out:
									self._usb_sd_endpoint_in = endpoint_in
									self._usb_sd_endpoint_out = endpoint_out
									break

		# if we don't have endpoints for SD upload then use the regular ones
		if not self._usb_sd_endpoint_out:
			self._usb_sd_endpoint_in = self._usb_cmd_endpoint_in
			self._usb_sd_endpoint_out = self._usb_cmd_endpoint_out
		self._logger.debug(
			"  cmd_endpoint_out 0x{:02x}, cmd_endpoint_in 0x{:02x}".
			format(self._usb_cmd_endpoint_out, self._usb_cmd_endpoint_in))
		self._logger.debug(
			"  sd_endpoint_out 0x{:02x}, sd_endpoint_in 0x{:02x}".
			format(self._usb_sd_endpoint_out, self._usb_sd_endpoint_in))
		if not (self._usb_cmd_endpoint_in and self._usb_cmd_endpoint_out):
			self.close()
			raise FlashForgeError('Unable to find USB endpoints - turn on debug output and check octoprint.log')

		self._keep_alive_t = threading.Thread(target=self.keep_alive, name="FlashForge.Keep_Alive")
		self._keep_alive_t.daemon = True
		self.enable_keep_alive(True)
		self._keep_alive_t.start()
		self._plugin.on_connect(self)

	@property
	def timeout(self):
		"""Return timeout for reads. OctoPrint Serial Factory property"""

		self._logger.debug("timeout()")
		return self._read_timeout

	@timeout.setter
	def timeout(self, value):
		"""Set timeout for reads. OctoPrint Serial Factory property"""

		self._logger.debug("Setting read timeout to {}s".format(value))
		self._read_timeout = value

	@property
	def write_timeout(self):
		"""Return timeout for writes. OctoPrint Serial Factory property"""

		self._logger.debug("write_timeout()")
		return self._write_timeout

	@write_timeout.setter
	def write_timeout(self, value):
		"""Set timeout for writes. OctoPrint Serial Factory property"""

		self._logger.debug("Setting write timeout to {}s".format(value))
		self._write_timeout = value

	@property
	def port(self):
		"""port name. OctoPrint Serial Factory property"""
		return self._portname

	def _valid_command(self, command):
		""" Check if command is valid for FF (allow line numbers N for emergency shutdown M112)

		M117 seems to cause issues during SD printing, but has to get this far to allow DisplayLayerPlugin to work
		"""
		gcode = command.split(b' ', 1)[0]
		return (gcode[0] in b"GMN") and gcode not in [b"M117"]

	def keep_alive(self):
		"""Keep printer connection alive

		Some printers drop the connection if they don't receive something at least every 4s, so we will send M119 to
		get status every few seconds.
		Also use for auto-reporting temperature so we can pass temp to Octoprint when the print queue is blocked by
		printer waiting for heatup, etc otherwise OctoPrint will think the printer is not responding...
		"""
		exit_flag = threading.Event()
		self._status_time = 0.0
		self._temp_time = 0.0
		keep_alive = 0.5
		self._logger.debug("keep_alive() set to:{}".format(keep_alive))
		# do not queue commands if the connection is going away
		while self._handle and not self._disconnect_event:
			if self._keep_alive_enabled:
				# even though we have blocking on the write() routine we do not want to try to write while uploading to
				# SD etc since it can generate confusion when the upload completes and a keep alive goes through at the
				# same time
				self._temp_time += keep_alive
				if self._temp_interval and self._temp_time >= self._temp_interval:
					# do the fake auto reporting of temp OctoPrint
					self._is_autotemp = True
					self.write(b"M105")
					self._temp_time = 0.0
				self._status_time += keep_alive
				if self._status_time >= 2.0:
					# get status every 2s so printer gets something during long ops
					# Dremel 3D20 seems to require something at least every 2s - other FF printers seem to be able to wait up to 3.5s
					# may want to make this a setting
					self.write(b"M119")
					self._status_time = 0.0
			if exit_flag.wait(timeout=keep_alive):
				exit()
		self._logger.debug("keep_alive() exiting")

	def enable_keep_alive(self, enable):
		"""Disable keep alive if we are streaming to the printer - eg file upload
		Even though there is blocking on the read/write this helps prevent issues/simplifies
		debugging during file upload and triggering a print
		"""
		self._logger.debug("enable_keep_alive({})".format(enable))
		self._keep_alive_enabled = enable
		self._temp_time = 0.0
		self._status_time = 0.0

	def is_ready(self):
		"""Return true if the printer is idle"""

		self._logger.debug("is_ready()")
		return self._printerstate == self.STATE_READY

	def is_printing(self):
		"""Return true if the printer is in any printing state"""

		self._logger.debug("is_printing()")
		return self._printerstate in self.PRINTING_STATES

	def is_sd_printing(self):
		"""Return true if the printer is in any printing state"""

		self._logger.debug("is_sd_printing()")
		return self._printerstate in [self.STATE_SD_PAUSED, self.STATE_SD_BUILDING]

	def disable_autotemp(self):
		"""Disable simulated auto temp reporting if printer claims to do it"""
		self._autotemp_enabled = False

	def disable_G91(self, disable):
		"""Disable G91 support if prefs indicate printer does not support relative positioning"""
		self._noG91 = disable

	def write(self, data):
		"""Write commands to printer. OctoPrint Serial Factory method

		Formats the commands sent by OctoPrint to make them FlashForge friendly.
		"""

		self._logger.debug("write() called by thread {}".format(threading.currentThread().getName()))
		if not self._handle:
			# do not queue commands if the connection is going away
			return

		self._writelock.acquire()

		# save the length for return on success
		data_len = len(data)

		# strip carriage return, etc so we can terminate lines the FlashForge way
		data = data.strip(b" \r\n")

		# try to filter out garbage commands (we need to replace with something harmless)
		# do this here instead of octoprint.comm.protocol.gcode.sending hook so DisplayLayerProgress plugin will work
		if len(data) and not self._valid_command(data):
			self._logger.debug("filtering command {0}".format(data.decode()))
			data = b"M105"
		else:
			cmd = data.split(b' ', 1)
			payload = b"" if len(cmd) == 1 else cmd[1]
			gcode = cmd[0]

			# special handling for relative positioning support
			if gcode in [b"G0", b"G1"] and self._noG91 and self._relative_pos:
				# try to convert relative positioning to absolute
				self._logger.debug("G0/G1 with rel pos")
				match = FlashForge.regex_g1.search(data)
				if match:
					self._logger.debug("G1 {}".format(match.groupdict()))
					data = b"G1"
					for k, v in match.groupdict().items():
						if v != None:
							if k in ['X', 'Y', 'Z']:
								v = self._pos[k] + float(v)
								data += b" %s%06.4f" % (k.encode(), v)
							elif k == 'E':
								self._logger.debug("extruder {}, {}".format(self._extruder, self._pos[self._extruder]))
								v = self._pos[self._extruder] + float(v)
								data += b" %s%06.4f" % (k.encode(), v)
							else:
								v = int(v)
								data += b" %s%d" % (k.encode(), v)
			elif gcode == b"G90":
				self._relative_pos = False
			elif gcode == b"G91":
				self._relative_pos = True
				if self._noG91:
					data = b"G90"
			elif gcode == b"M23":
				# we started an SD print - make sure to set printer state
				self._status_time = 0.0
				data += b"\r\n~M119"
			elif gcode == b"M27":
				# make sure we have the current printer status before getting SD card progress, because SD card
				# progress reports printing when cancelled or finished...
				self._status_time = 0.0
				data = b"M119\r\n~M27"
			elif gcode == b"M105":
				self._temp_time = 0.0
			elif gcode == b"M108":
				self._extruder = "E1" if b"T1" in payload else "E0"
				self._logger.debug("select extruder {0}".format(self._extruder))
			elif gcode == b"M601":
				# make sure we have the current printer status as soon as we connect
				self._status_time = 0.0
				data += b"\r\n~M119"

		try:
			self._logger.debug("write() {0}".format(data.decode()))
			self._handle.bulkWrite(self._usb_cmd_endpoint_out, b"~%s\r\n" % data, int(self._write_timeout * 1000.0))
			self._writelock.release()
			return data_len
		except usb1.USBError as usberror:
			self._writelock.release()
			raise FlashForgeError('USB Error write()', usberror)

	def writeraw(self, data, command = True):
		"""Write raw data to printer.

		data: bytearray to send
		command: True to send g-code, False to send to upload SD card
		"""

		self._logger.debug("writeraw() called by thread {}".format(threading.currentThread().getName()))

		try:
			self._handle.bulkWrite(self._usb_cmd_endpoint_out if command else self._usb_sd_endpoint_out, data)
			return len(data)
		except usb1.USBError as usberror:
			raise FlashForgeError('USB Error writeraw()', usberror)

	def readline(self):
		"""Read line worth of response from printer. OctoPrint Serial Factory method

		Read response from the printer and store as a series of \r\n terminated lines
		OctoPrint reads response line by line..

		Returns:
			List of lines returned from the printer
		"""

		self._logger.debug("readline() called by thread {}".format(threading.currentThread().getName()))

		self._readlock.acquire()

		# return any line we have buffered
		if not self._incoming.empty():
			self._readlock.release()
			return self._incoming.get_nowait()

		# fetch some data
		data = self.readraw()
		# parse and buffer it
		data = self._parse_response(data)
		if b"CMD M601 " in data:
			# should also be getting a status response
			status = self.readraw()
			# parse and buffer it
			data += self._parse_response(status)

		self._readlock.release()
		# return the buffer
		return self._incoming.get_nowait()

	def _parse_response(self, data):
		"""Parse raw data from printer into lines and buffer them

		Manipulates printer response if necessary into something OctoPrint understands, breaks into lines and stores
		in a buffer for readline() method.
		"""
		if len(data):
			if b"CMD M27 " in data:
				# need to filter out bogus SD print progress from cancelled or paused prints
				if b"printing byte" in data:
					match = FlashForge.regex_SDPrintProgress.search(data)
					if match:
						try:
							current = int(match.group("current"))
							total = int(match.group("total"))
						except:
							pass
						else:
							# Note: there is an issue with .gx files indicating the current byte size is greater than the
							# total when the print is started
							if self._printerstate == self.STATE_READY and current >= total:
								# Ultra 3D: after completing print it still indicates SD card progress
								data = b"CMD M27 Received.\r\nDone printing file\r\nok\r\n"
							elif self._printerstate in [self.STATE_SD_PAUSED, self.STATE_SD_BUILDING] and \
								not self._comm.isSdFileSelected():
								# user manually started a print or we connected while one was running
								data = b"File opened: SD_printing.gcode Size: %d\r\nok\r\n" % total
							elif self._printerstate == self.STATE_SD_PAUSED:
								# when paused still printer indicates printing so change the response
								# TODO: there may be a proper way to signal this using "action"?
								data = b"CMD M27 Received.\r\nPrinting paused\r\nok\r\n"
								if self._comm.isSdPrinting():
									# this is for when we connect and the printer is printing but paused or the user
									# manually paused the print using the printer screen. doesn't seem to be a way to
									# tell OctoPrint the correct state so we do it the dirty way
									self._comm._changeState(self._comm.STATE_PAUSED)
							elif self._printerstate != self.STATE_SD_BUILDING:
								# after print is cancelled M27 always looks like its printing from sd card
								data = b"CMD M27 Received.\r\nNot SD printing\r\nok\r\n"

				elif not data.strip().endswith(b"ok"):
					# for Dremel 3D20 not responding correctly when not printing from SD card:
					if self._printerstate == self.STATE_READY:
						data = b"CMD M27 Received.\r\nDone printing file\r\nok\r\n"
					else:
						data += b"ok\r\n"

			elif b"CMD M105 " in data:
				if self._is_autotemp:
					# this was generated as an auto temp report by our keep alive so filter out the CMD and OK
					# so as not to confuse the OctoPrint buffer counter
					data = data.replace(b"CMD M105 Received.\r\n", b"")
					# TODO: add " W:?" to the string to indicate that the printer is waiting to get to temp if state
					#  indicates waiting on tool or bed. This should prevent OctoPrint from triggering timeouts?
					if not (b"CMD " in data and self._printerstate in [self.STATE_SD_BUILDING, self.STATE_SD_PAUSED]):
						# do not drop the "ok" if there is the response to another command in here and we are printing from SD?
						data = data.replace(b"\r\nok", b"")
				self._is_autotemp = False

			elif b"CMD M114 " in data:
				# looks like get current position returns A: and B: for extruders?
				data = data.replace(b" A:", b" E0:").replace(b" B:", b" E1:")
				match = FlashForge.regex_M114position.search(data)
				if match:
					for k, v in match.groupdict().items():
						if v != None:
							self._pos[k] = float(v)
					self._logger.debug("pos: {}".format(self._pos))

			elif b"CMD M115 " in data:
				# Try to make the firmware response more readable by OctoPrint
				data = data.replace(b"Firmware:", b"FIRMWARE_NAME: FlashForge VER:")

			elif b"CMD M119 " in data:
				# this was generated by us so do not return anything to OctoPrint
				oldstate = self._printerstate
				if b"MachineStatus: READY" in data:
					if b"MoveMode: READY" in data:
						self._printerstate = self.STATE_READY
					elif b"MoveMode: WAIT_ON_TOOL" in data or b"MoveMode: WAIT_ON_PLATFORM" in data:
						# printing directly and printer waiting for bed or extruder to heat up
						self._printerstate = self.STATE_WAIT_ON_TEMP
					elif b"MoveMode: HOMING" in data:
						# printing directly and printer waiting for bed or extruder to heat up
						self._printerstate = self.STATE_HOMING
					else:
						# moving or homing
						self._printerstate = self.STATE_BUSY
				elif b"MachineStatus: BUILDING_FROM_SD" in data:
					if b"MoveMode: PAUSED" in data:
						self._printerstate = self.STATE_SD_PAUSED
					else:
						self._printerstate = self.STATE_SD_BUILDING
				else:
					self._printerstate = self.STATE_BUSY
				# Remove M119 response (assuming it is the last part of the response, other command may be at the front)
				# Typically if something is prepended, it will be a move related command.
				data = data.split(b"CMD M119 ")[0]
				if len(data) and (self._printerstate == self.STATE_READY or self._printerstate == self.STATE_SD_PAUSED):
					# If the printer is still moving it will send the ok associated with the command later. If it has
					# completed the movement a separate ok is never sent so we add it here
					data += b"ok\r\n"

				if oldstate != self._printerstate:
					self._logger.debug("state changed from {} to {}".format(oldstate, self._printerstate))
					# force temp reporting if busy while direct printing and waiting for extruder/bed to heat up
					# (unless printer reports autotemp) so OctoPrint sees something.
					# TODO: use OctoPrint state instead to decide when to do the temp check - ie if printing and temp wait
					if self._printerstate == self.STATE_WAIT_ON_TEMP and self._autotemp_enabled:
						self._temp_interval = settings().getFloat(["serial", "timeout", "temperatureAutoreport"])
					else:
						self._temp_interval = 0.0
					# TODO: if we just connected and the printer is printing from SD then trigger an M27 to get
					#		OctoPrint to detect SD printing

			if len(data):
				# turn data into list of lines
				datalines = data.splitlines()
				for i, line in enumerate(datalines):
					self._logger.debug("buffering: {}".format(line))
					self._incoming.put(line)
			else:
				self._incoming.put(data)

		else:
			self._incoming.put(data)

		return data

	def readraw(self, timeout=-1):
		"""
		Read everything available from the from the printer

		Parameters:
			timeout : max time to wait in ms

		Returns:
			String containing response from the printer
		"""

		data = b""
		if timeout == -1:
			timeout = int(self._read_timeout * 1000.0)
		self._logger.debug("readraw() called by thread: {}, timeout: {}".format(threading.currentThread().getName(), timeout))

		try:
			# read data from USB until ok signals end or timeout
			while not data.strip().endswith(b"ok"):
				data += self._handle.bulkRead(self._usb_cmd_endpoint_in, self.BUFFER_SIZE, timeout)
		except usb1.USBErrorTimeout:
			self._logger.debug("readraw() TIMEOUT")
		except usb1.USBError as usberror:
			raise FlashForgeError("USB Error readraw()", usberror)

		self._logger.debug("readraw() returns: {}".format(data.decode().replace("\r\n", " | ")))
		return data

	def sendcommand(self, cmd, timeout=1000, readresponse=True):
		"""
		Send g-code to printer and wait for a response

		Parameters:
			cmd : FF formatted g-code command
			timeout : max time to wait in ms
			readresponse : true to return printer response

		Returns:
			True if printer responded with ok, indicating command was accepted
			Optional : string containing response from the printer
		"""

		self._logger.debug("sendcommand() {}".format(cmd.decode()))

		self.writeraw(b"~%s\r\n" % cmd)
		if not readresponse:
			return True, None

		# read response, make sure we are getting the command we sent
		gcode = b"CMD %s " % cmd.split(b" ", 1)[0]
		response = b""
		while True:
			response = self.readraw(timeout)
			# TODO: if response is multiline and contains response to a previous command as well as this one then
			#  we lose the previous command. We might need to parse each line and save old responses into the buffer
			if not response or gcode in response:
				break
			# we got the response from some previous OctoPrint command so parse it into the buffer used for
			# OctoPrint listener so it will be read later
			self._parse_response(response)
		# note that sometimes the ok response is not terminated with \r\n eg M104 on Dreamer
		if b"\r\nok" in response:
			self._logger.debug("sendcommand() got an ok")
			return True, response
		return False, response

	def makeexclusive(self, exclusive):
		"""	Obtain exclusive use of the connection for the current thread"""

		if exclusive:
			self._readlock.acquire()
			self._writelock.acquire()
		else:
			self._readlock.release()
			self._writelock.release()

	def close(self):
		"""	Close USB connection and cleanup. OctoPrint Serial Factory method"""

		self._logger.debug("close()")

		self._disconnect_event = True
		if self._keep_alive_t:
			self._keep_alive_t.join()

		# cleanup
		if self._handle:
			self._logger.debug("closing handle...")
			if not self._readlock.locked():
				# TODO: try to fetch any pending replies from the printer.
				#  This doesn't really work properly right now as sometimes the printer stops returning responses...
				#  Unfortunately if we close the port without reading all pending data it seems to break subsequent
				#  connections to the printer, requiring a printer reboot
				self._readlock.acquire()
				try:
					while True:
						data = self._handle.bulkRead(self._usb_cmd_endpoint_in, self.BUFFER_SIZE, 3000)
						self._logger.debug("bulkRead() {}".format(data.decode().replace("\r\n", " | ")))
				except usb1.USBError as usberror:
					self._logger.debug("bulkRead() error {}".format(usberror))
					pass
				self._readlock.release()
			try:
				self._handle.releaseInterface(0)
			except usb1.USBError as usberror:
				self._logger.debug("Error releasing handle {}".format(usberror))
				pass
			try:
				self._handle.close()
			except usb1.USBError as usberror:
				raise FlashForgeError("Error closing USB handle", usberror)
			self._handle = None

		self._incoming = None

		self._plugin.on_disconnect()


from django.urls import re_path

from bag_transfer.rights.views import (RightsAPIAdminView, RightsCreateView,
                                       RightsDetailView, RightsUpdateView)

app_name = 'rights'

urlpatterns = [
    re_path(r"^add/$", RightsCreateView.as_view(), name="add"),
    re_path(r"^(?P<pk>\d+)/$", RightsDetailView.as_view(), name="detail"),
    re_path(r"^(?P<pk>\d+)/edit$", RightsUpdateView.as_view(), name="edit"),
    re_path(
        r"^(?P<pk>\d+)/(?P<action>(delete))/$", RightsAPIAdminView.as_view(), name="api"
    ),
]


from fastapi import FastAPI

import pm4py

import os
import shutil

from src.enums.ConstraintChecker import ConstraintChecker
from src.machine_learning.utils import *
from src.machine_learning import *

app = FastAPI()

@app.get("/")
def recommend():
        # ================ inputs ================
        support_threshold = 0.75
        train_log_path = "media/input/log/train.xes"
        test_log_path = "media/input/log/test.xes"
        checkers = [
            ConstraintChecker.EXISTENCE,
            ConstraintChecker.ABSENCE,
            ConstraintChecker.INIT,
            ConstraintChecker.EXACTLY,
            ConstraintChecker.CHOICE,
            ConstraintChecker.EXCLUSIVE_CHOICE,
            ConstraintChecker.RESPONDED_EXISTENCE,
            ConstraintChecker.RESPONSE,
            ConstraintChecker.ALTERNATE_RESPONSE,
            ConstraintChecker.CHAIN_RESPONSE,
            ConstraintChecker.PRECEDENCE,
            ConstraintChecker.ALTERNATE_PRECEDENCE,
            ConstraintChecker.CHAIN_PRECEDENCE,
            ConstraintChecker.NOT_RESPONDED_EXISTENCE,
            ConstraintChecker.NOT_RESPONSE,
            ConstraintChecker.NOT_CHAIN_RESPONSE,
            ConstraintChecker.NOT_PRECEDENCE,
            ConstraintChecker.NOT_CHAIN_PRECEDENCE
        ]
        prefixing = {
            "type": PrefixType.UPTO,
            "length": 5
        }
        rules = {
            "vacuous_satisfaction": True,
            "activation": "", # e.g. A.attr > 6
            "correlation": "", # e.g. T.attr < 12
            "n": {
                ConstraintChecker.EXISTENCE: 1,
                ConstraintChecker.ABSENCE: 1,
                ConstraintChecker.EXACTLY: 1,
            }
        }
        labeling = {
            "type": LabelType.TRACE_DURATION,
            "threshold_type": LabelThresholdType.LABEL_MEAN,
            "target": TraceLabel.TRUE, # lower than a threshold considered as True
            "trace_attribute": "",
            "custom_threshold": 0.0
        }
        # ================ inputs ================

        # recreate ouput folder
        shutil.rmtree("media/output", ignore_errors=True)
        os.makedirs(os.path.join("media/output/result"))

        # generate rules
        rules["activation"] = generate_rules(rules["activation"])
        rules["correlation"] = generate_rules(rules["correlation"])

        # read the files
        train_log = pm4py.read_xes(train_log_path)
        test_log = pm4py.read_xes(test_log_path)

        # generate recommendations and evaluation
        recommendations, evaluation = generate_recommendations_and_evaluation(test_log=test_log, train_log=train_log,
                                                                              labeling=labeling,
                                                                              prefixing=prefixing,
                                                                              support_threshold=support_threshold,
                                                                              checkers=checkers,
                                                                              rules=rules)

        return {"recommendations": recommendations, "evaluation": evaluation}


"""
Abby Mueller
"""

import pandas as pd
import numpy as np
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
#import requests
#from bs4 import BeautifulSoup as bs
#from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
from PIL import Image, ImageDraw, ImageFont
import urllib.request
from pathlib import Path #check if images exist or not
import random

#set environment variables https://phoenixnap.com/kb/set-environment-variable-mac
class SongMarkov:
    """
    Class for implementing a markov chain of songs, based off a transition matrix passed
    during construction. Currently am passing a matrix based off spotify playlist
    """
    def __init__(self, transition_matrix):
        self.transition_matrix = transition_matrix
        self.indices = list(transition_matrix.keys())

    def get_next_song(self, curr_song):
        """
        Args: curr_song is index of current song being passed
        """
        return np.random.choice(
            self.indices,
            p=[self.transition_matrix[curr_song][next_index] for next_index in self.indices]
        )

    def create_transitions(self, current_song, len_param=10):
        """
        Args: current song (int) is index of song being examined
        len_param (int) is how many transitions to make
        (default 10)

        returns the list of transitions between songs
        """
        songs = []
        while len(songs) < len_param:
            next_song= self.get_next_song(current_song)
            songs.append(next_song)

        return songs

        #markov chain of probabilities of

def get_playlist_id():
    """
    Seeks user input to get playlist ID
    returns spotify playlist id in Spotipy format
    """
    print("What is the id of the playlist?")
    play_id_num = input()

    if play_id_num.startswith("https://open.spotify.com"):
        play_id_num = play_id_num[34:]

    return 'spotify:playlist:' + str(play_id_num)

def get_playlist_track_info(sp, uri):
    """
    Get playlist track info and aggregate into dataframes.
    Args:
    sp, spotipy credentials object
    uri, resource id for playlist

    """
    track_uri = []
    track_name = []
    track_artist = []

    offset = 0 #tracks how many items in the playlist we look at
    response = sp.playlist_items(uri,
                                offset=offset,
                                fields='items.track.id,items.track.name,items.track.artists, total',
                                additional_types=['track'])

    if len(response['items']) == 0:
        print("Invalid playlist- no songs")
    else:
        df1 = pd.DataFrame(response)
        for i, x in df1['items'].items():

            artists = x["track"]['artists']

            track_uri.append(x["track"]['id'])
            track_name.append(x["track"]['name'])
            artist_name = artists[0]["name"]

            #handle multiple artists
            if len(artists) > 1:
                artist2_name = artists[1]["name"]

                track_artist.append([artist_name, artist2_name])
            else:
                track_artist.append([artist_name])

        df2 = pd.DataFrame({
            'id':track_uri,
            'name': track_name,
            'artist': track_artist
        })

        offset = offset + len(response['items'])

        return df2, offset

def create_matrix(df):
    """
    Given a df of form id, name, artist,
    creates a transition matrix from the song title lengths.
    """
    #get lengths of each song title, total up
    total_length = 0
    for song in df["name"]:
        total_length += len(song)

    differences = {}

    for i in range(len(df["name"])):
        differences[i] = {}
        for j, song in enumerate(df["name"]):
            differences[i][j] = len(song) / total_length

        #corrects for floating point rounding yielding a number just under 1
        if (sum(differences[i].values())) < 1:
            differences[i][0] += (1 - sum(differences[i].values()))

    return differences

def get_image(sp,artist_name):
    """
    Using spotipy, gets the image from Spotify associated with artist.
    sp (spotify credentials object)
    artist_name (str) is name artist.
    returns str image URL
    """
    image = ""

    name = artist_name
    results = sp.search(q='artist:' + name, type='artist')
    items = results['artists']['items']
    if len(items) > 0:
        artist = items[0]
        image = artist['images'][0]['url']

    return image

#sample playlist ids
#1umwX5x9YfdOYZDWR5BjUO

#short
#4V2lefCcuGNzHe0hjvMx1m

#playlist iteration from https://github.com/plamere/spotipy/blob/master/examples/playlist_tracks.py
def create_image_art(sp, df1, id, order):
    """
    Creates the image art, using spotify credentials to access images,
    data from provided dataframe (generated in earlier step from spotify)
    and the give order from the markov generator.
    playlist id is to get name to label the art.
    ARgs: sp, spotify credentials
        df1, dataframe of song id/artist/name
        id, playlist id
        order, generated song order
    Doesn't return anything but rather saves the artist images to be used
    and also saves a final image as final.jpg.
    """
    images = {}
    for i in order:
        images[i] = get_image(sp, df1["artist"][i][0] )
    #current path info stuff came from
    #https://stackoverflow.com/questions/3430372/how-do-i-get-the-full-path-of-the-current-files-directory

    curr_path = Path(__file__).parent.resolve()
    for key, value in images.items():
        #to save stuff into file
        full_path = str(curr_path) + "/images/" + str(key) + ".jpg"
        urllib.request.urlretrieve(value, full_path)

    plist = sp.playlist(id) #for generated image naming
    new_base = Image.open(str(curr_path) + "/images/" + str(order[0]) + ".jpg")
    with new_base as background:
        for i in (order):
            img = Image.open(str(curr_path) + "/images/"  + str(i) + ".jpg")
            img = img.convert("RGBA")
            #rgba color replacement
            #https://stackoverflow.com/questions/3752476/python-pil-replace-a-single-rgba-color
            data = np.array(img)
            r, g, b, a = data.T
            alpha = random.randint(0, 200)

            white_areas = (r == 255) & (b == 255) & (g == 255) & (a == alpha)
            data[..., :-1][white_areas.T] = (random.randint(0,255), random.randint(0,255), random.randint(0,255))
            img = Image.fromarray(data)
            img.putalpha(alpha)

            paste_location_x = random.randint(-200,200) #base is 750 px
            paste_location_y= random.randint(-200,200)
            img = img.rotate(random.randint(0, 360))

            background.paste(img, (paste_location_x,paste_location_y), img)
            temp = background.save(str(curr_path) + "/images/" + str(plist['name']) + ".jpg")

    #in this section we draw the playlist name onto the image
    #could probably have been separate function but alas
    plist = sp.playlist(id)

    k = Image.open(str(curr_path) + "/images/" + str(plist['name']) + ".jpg")
    txt = ImageDraw.Draw(k)

    #caveat: this works for Mac computers, for windows we would need to do "arial.tff" or somethine else
    fnt = ImageFont.truetype("/System/Library/Fonts/Supplemental/Arial Unicode.ttf", 28, encoding="unic")
    txt.text((100, 100), plist['name'], font=fnt, fill = (random.randint(0,255),random.randint(0,255),random.randint(0,255)))

    k.show() #for demo purposes
    #update and save
    k.save(str(curr_path) + "/images/" + str(plist['name']) + ".jpg")

def main():
    """
    Creates spotify object, then given a playlist id,
    generates a dataframe based off the playlist on Spotify and uses that
    in order to make a transition matrix and later to grab images for the art.
    Creates art based off song frequency using artist images from spotify.
    """
    sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials())
    id = get_playlist_id()
    df1, offset = get_playlist_track_info(sp, id)

    matrix = create_matrix(df1)

    #instantiate markov chain
    transitioner = SongMarkov(matrix)
    #starting vector is that any song has a likelihood of being chosen, in order to allow
    #for higher chance of unique images being generated each time
    first_song = np.random.choice(transitioner.indices)
    #15 transitions made
    order = transitioner.create_transitions(first_song, 15)

    create_image_art(sp, df1, id, order)

if __name__ == "__main__":
    main()


from GUI.guiImports import *

start_date_global = "N/A"
num_days_global = "N/A"
spreadsheet_global = False

def exportGlobalVariables():
    return start_date_global, num_days_global, spreadsheet_global

def get_download_path():
    """Returns the default downloads path for linux or windows"""
    if os.name == 'nt':
        sub_key = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
        downloads_guid = '{374DE290-123F-4565-9164-39C4925E467B}'
        with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key:
            location = winreg.QueryValueEx(key, downloads_guid)[0]
        return location
    else:
        return os.path.join(os.path.expanduser('~'), 'downloads')

def download_output():
    try:
        if platform == "darwin":
            downloads_path = str(Path.home() / "Downloads")
            downloads_path = downloads_path + "/output.xlsx"
            output_path = get_mac_directory() + "/Spreadsheets/output.xlsx"
        else:
            downloads_path = get_download_path()
            downloads_path = os.path.join(downloads_path, "output.xlsx")
            output_path = os.getcwd() + "/Spreadsheets/output.xlsx"
        shutil.copyfile(output_path, downloads_path)
        popup("Success", "Downloaded Successfully")
    except:
        popup("Error", "Downloaded Failed")

def refresh_variables(start_date_label, num_days_label, spreadsheet_label):
    start_date_label.config(text=f"Start Date: {start_date_global}")
    num_days_label.config(text=f"Num Days in Cycle: {num_days_global}")
    spreadsheet_label.config(text=f"SpreadSheet: {spreadsheet_global}")

def ChangeScreen(window, screen, frame):
    for widget in frame.winfo_children():
        widget.destroy()
    screen(window)

def popup(title, given_message):  # Popup when an image is successfully uploaded
    # Initialize popup
    win = Toplevel()
    win.wm_title(title)
    winx = 450
    winy = 200
    win.minsize(winx, winy)
    win.maxsize(winx, winy)
    win.geometry("400x300+400+200")

    # Title of the popup
    message = Label(win, text=title, font=('Ariel', 20))
    message.pack(side=TOP, pady=10)

    # Message of the popup
    if len(given_message) > 45:
        given_message1 = given_message[0:45]
        given_message2 = given_message[45:len(given_message)]
        message = Label(win, text=given_message1, font=('Ariel', 13))
        message.pack(side=TOP, pady=6)
        message = Label(win, text=given_message2, font=('Ariel', 13))
        message.pack(side=TOP)
    else:
        message = Label(win, text=given_message, font=('Ariel', 13))
        message.pack(side=TOP, pady=10)

    # Create canvas
    canvas = Canvas(win, width=winx, height=winy)
    canvas.pack(side=LEFT)

    # Exit button to close the popup window
    exitpop = Button(win, text="Okay", command=win.destroy, height=2, width=12)
    exitpop.place(x=(winx/2)-55, y=winy-60)

def popup_large(title, given_message):  # Popup when an image is successfully uploaded
    # Initialize popup
    win = Toplevel()
    win.wm_title(title)

    win.geometry("600x400+400+200")

    Grid.columnconfigure(win, 0, weight=1)

    Grid.rowconfigure(win, 0, weight=1)
    Grid.rowconfigure(win, 1, weight=3)
    Grid.rowconfigure(win, 2, weight=1)

    # Title of the popup
    message = Label(win, text=title, font=('Ariel', 20))
    message.grid(row=0, column=0, sticky="nsew")

    # Message of the popup
    message2 = Label(win, text=given_message, font=('Ariel', 13), borderwidth=0, anchor="w", justify=LEFT)
    message2.grid(row=1, column=0, sticky="new", pady=10, padx=4)

    # Exit button to close the popup window
    exitpop = Button(win, text="Okay", command=win.destroy, height=2, width=12)
    exitpop.grid(row=2, column=0, sticky="s", pady=10)

def popup_input():  # Popup when an image is successfully uploaded
    # Initialize popup
    win = Toplevel()
    win.wm_title("New Cycle")
    winx = 450
    winy = 270
    win.minsize(winx, winy)
    win.maxsize(winx, winy)
    win.geometry("450x270+400+200")

    # Title of the popup
    message = Label(win, text="Create New Cycle", font=('Ariel', 20))
    message.pack(side=TOP, pady=10)

    start_date_label = Label(win, text="Cycle Start Date(YYYY-MM-DD)", font=('Ariel', 12))
    start_date_label.place(x=10, y=58)

    # User Input field
    start_date_input = Entry(win)
    start_date_input.place(x=240, y=60)
    start_date_input.focus_set()

    num_days_label = Label(win, text="Number Days in Cycle", font=('Ariel', 12))
    num_days_label.place(x=10, y=98)

    # User Input field
    num_days_input = Entry(win)
    num_days_input.place(x=240, y=100)
    num_days_input.focus_set()

    upload_excel = Button(win, text="Upload SpreadSheet", command=lambda: openExcelSheet(), height=2,
                     width=18)
    upload_excel.place(x=(winx / 2) - 55, y=winy - 115)

    # Exit button to close the popup window
    exitpop = Button(win, text="Okay", command=lambda: exit_input(win, start_date_input, num_days_input), height=2, width=12)
    exitpop.place(x=(winx/2)-38, y=winy-60)

def exit_input(win, start_date_input, num_days_input):
    global start_date_global, spreadsheet_global, num_days_global
    start_date, num_days = captureUserInput(start_date_input, num_days_input)
    error = 0
    error_message = 'Undefined: '
    if start_date == '':
        error += 1
        error_message += "Start Date"
    if num_days == '':
        if error > 0:
            error_message += "/"
        error += 1
        error_message += "Number of Days"
    if os.name == 'nt':
        dir_spreadsheets = os.getcwd() + '/Spreadsheets'
    else:
        dir_spreadsheets = get_mac_directory() + "/Spreadsheets"
    numSpreadSheets = len([name for name in os.listdir(dir_spreadsheets) if os.path.isfile(os.path.join(dir_spreadsheets, name))])
    if numSpreadSheets <= 0:
        if error > 0:
            error_message += "/"
        error += 1
        error_message += "Spreadsheet"
    else:
        spreadsheet_global = True
    if error > 0:
        popup("Error", error_message)
    start_date_global = start_date
    num_days_global = num_days
    win.destroy()

def openExcelSheet():
    # Open the excel sheet
    file1 = fd.askopenfile(mode="r")
    fileaddress = file1.name

    # Get the excel spreadsheet name
    filename = ''
    for letter in fileaddress:
        filename += letter
        if letter == '/':
            filename = ''

    # Copy spreadsheet to folder
    if os.name == 'nt':
        excelfolder_dir = os.getcwd() + "/Spreadsheets"  # Find images folder
    else:
        excelfolder_dir = get_mac_directory() + "/Spreadsheets"  # Find images folder

    shutil.copyfile(file1.name, os.path.join(excelfolder_dir, filename))

# Capture user input
def captureUserInput(start_date_input, num_days_input):
    start_date = start_date_input.get()
    num_days_input = num_days_input.get()
    return start_date, num_days_input


# Unused file because of using ORM
# Left it here to show that I understand
# how to create DB and Tables by SQL

from clickhouse_driver import Client

def create_table(client):

    with open('sql/old/create_test_database.sql') as f:
        query = f.read()
        result = client.execute(query)

    with open('sql/old/create_event_table.sql') as f:
        query = f.read()
        result = client.execute(query)

    with open('sql/old/create_event_log_table.sql') as f:
        query = f.read()
        result = client.execute(query)

if __name__ == "__main__":
    client = Client('localhost')
    create_table(client)


from argparse import ArgumentParser
from typing import Dict, List

def read_data(path: str):
    data: Dict[str, List[str]] = {}

    with open(path) as f:
        for line in f:
            line = line.strip()
            if not line:
                continue

            instance_id, *sense_keys = line.split()
            data[instance_id] = sense_keys

    return data

def do_majority_voting(gold_data, system_data, system_ranking, use_system_ranking=False):
    keys = {}

    for gold_instance_id, gold_sense_keys in gold_data.items():
        answers = {}

        for system_name, system_predictions in system_data.items():
            if gold_instance_id not in system_predictions:
                continue

            system_sense_keys = system_predictions[gold_instance_id]
            for system_sense_key in system_sense_keys:
                if system_sense_key not in answers:
                    answers[system_sense_key] = 0

                if use_system_ranking:
                    answers[system_sense_key] += system_ranking[system_name]
                else:
                    answers[system_sense_key] += 1

            majority_key = max(answers, key=answers.get)
            keys[gold_instance_id] = majority_key

    return keys

if __name__ == '__main__':
    parser = ArgumentParser()

    parser.add_argument(
        '--gold_path',
        type=str,
        required=True,
        help='Path to the gold keys.'
    )
    parser.add_argument(
        '--ares_path',
        type=str,
        required=True,
        help='Path to the keys predicted by ARES.'
    )
    parser.add_argument(
        '--bem_path',
        type=str,
        required=True,
        help='Path to the keys predicted by BEM.'
    )
    parser.add_argument(
        '--esc_path',
        type=str,
        required=True,
        help='Path to the keys predicted by ESC.'
    )
    parser.add_argument(
        '--ewiser_path',
        type=str,
        required=True,
        help='Path to the keys predicted by EWISER.'
    )
    parser.add_argument(
        '--generationary_path',
        type=str,
        required=True,
        help='Path to the keys predicted by Generationary.'
    )
    parser.add_argument(
        '--glossbert_path',
        type=str,
        required=True,
        help='Path to the keys predicted by GlossBERT.'
    )
    parser.add_argument(
        '--syntagrank_path',
        type=str,
        required=True,
        help='Path to the keys predicted by SyntagRank.'
    )
    parser.add_argument(
        '--output_path',
        type=str,
        required=True,
        help='Path to the keys that were not predicted correctly by any system.'
    )
    parser.add_argument(
        '--use_system_ranking',
        action='store_true',
        help='Use this flag to perform a ranked ensemble.'
    )

    args = parser.parse_args()

    gold_path: str = args.gold_path
    ares_path: str = args.ares_path
    bem_path: str = args.bem_path
    esc_path: str = args.esc_path
    ewiser_path: str = args.ewiser_path
    generationary_path: str = args.generationary_path
    glossbert_path: str = args.glossbert_path
    syntagrank_path: str = args.syntagrank_path
    output_path: str = args.output_path
    use_system_ranking: bool = args.use_system_ranking

    gold_data: Dict[str, List[str]] = read_data(gold_path)
    system_data: Dict[str, Dict[str, List[str]]] = {
        'ares': read_data(ares_path),
        'bem': read_data(bem_path),
        'esc': read_data(esc_path),
        'ewiser': read_data(ewiser_path),
        'generationary': read_data(generationary_path),
        'glossbert': read_data(glossbert_path),
        'syntagrank': read_data(syntagrank_path),
    }
    system_ranking: Dict[str, int] = {
        'ares': 5,
        'bem': 6,
        'esc': 7,
        'ewiser': 4,
        'generationary': 2,
        'glossbert': 3,
        'syntagrank': 1,
    }

    keys = do_majority_voting(gold_data, system_data, system_ranking, use_system_ranking=use_system_ranking)

    sorted_instance_ids = sorted(list(keys.keys()))
    with open(output_path, 'w') as f:
        for instance_id in sorted_instance_ids:
            sense_key = keys[instance_id]
            f.write(f'{instance_id} {sense_key}\n')


import numpy as np
def read_height_weight():
    list_hw = []
    for k in range(int(input())) :
        h,w = input().split()
        list_hw.append((int(h),int(w)))
    return np.array(list_hw)
def cm_to_m(x):
    return x/100
def cal_bmi(hw):
    calculated=[]
    for h,w in hw:
        calculated.append( w/ (cm_to_m(h)**2) )
    return np.array(calculated)
def main():
    hw = read_height_weight()
    bmi = cal_bmi(hw)
    avg_bmi = sum(cal_bmi(hw))/len(hw)
    count_underweight = sum(cal_bmi(hw)<18.5)
    print('average bmi =', avg_bmi)
    print('#bmi < 18.5 =', count_underweight)
exec(input().strip())


#https://pysource.com/2021/10/29/kalman-filter-predict-the-trajectory-of-an-object/
import cv2
import numpy as np

class KalmanFilter:
    kf = cv2.KalmanFilter(4, 2)
    kf.measurementMatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32)
    kf.transitionMatrix = np.array([[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32)

    def predict(self, coordX, coordY):
        ''' This function estimates the position of the object'''
        measured = np.array([[np.float32(coordX)], [np.float32(coordY)]])
        self.kf.correct(measured)
        predicted = self.kf.predict()
        x, y = int(predicted[0]), int(predicted[1])
        return x, y


para = input("Enter a paragraph: ")
k1 = 0
k2 = 0
k3 = 0
words = para.split()
for i in words:
  if(i=='a'):
    k1=k1+1
  elif(i=='an'):
    k2=k2+1
  elif(i=='the'):
    k3=k3+1
print("Occurrences of the words a,an and the are respectively:")
print(k1,k2,k3)
print('total article in the paragraph are ',k1+k2+k3)


# 가장 큰 수

import functools

# 정답을 두개 봤는데
# 두개 다 좋다.
# a+b - b+a  로 좋은 접근법 같다.
def comparator(a,b):
    t1 = a+b
    t2 = b+a
    return (int(t1) > int(t2)) - (int(t1) < int(t2)) #  t1이 크다면 1  // t2가 크다면 -1  //  같으면 0

def solution(numbers):
    n = [str(x) for x in numbers]
    n = sorted(n, key=functools.cmp_to_key(comparator),reverse=True)
    answer = str(int(''.join(n)))
    return answer

# # 어차피 3자리니 이것도 좋을듯
# def solution(numbers):
#     numbers = list(map(str, numbers))
#     numbers.sort(key = lambda x: x*3, reverse=True)
#     return str(int(''.join(numbers)))


text = open('text.txt', 'r')
symbols = dict()
symbol_count = dict()
all_symbol = text.read().lower()
text.close()

for symbol in all_symbol:
    if symbol.isalpha():
        if symbol in symbols:
            symbols[symbol] += 1
        else:
            symbols[symbol] = 1

words_count = sum(symbols.values())

for word, frequency in symbols.items():
    frequency = round(frequency / words_count, 3)
    if frequency not in symbol_count:
        symbol_count[frequency] = {word}
    else:
        symbol_count[frequency].update(word)

analysis = open('analysis.txt', 'a')

for frequency, words_set in sorted(symbol_count.items(), reverse=True):
    for word in sorted(words_set):
        analysis.write(word + ' ' + str(frequency) + '\n')

analysis.close()


import unittest
import nltk
from datamason.text_analysis import text_analysis, pos_tag_text
from nltk.probability import FreqDist
from nltk.stem import WordNetLemmatizer
from nltk.tokenize import word_tokenize, sent_tokenize
from nltk.tag import pos_tag
from unittest.mock import patch

try:
    # Download the tagger
    nltk.download('averaged_perceptron_tagger')
except Exception as e:
    print(f'Error downloading nltk tagger: {e}')

class TestFunctions(unittest.TestCase):

    def test_sent_tokenize_text(self):
        try:
            # Example text
            text = "This is a sentence. Here is another one."

            # Call the sent_tokenize_text function with the defined text
            result = text_analysis.sent_tokenize_text(text)

            # Expected result using NLTK's sent_tokenize function
            expected_result = sent_tokenize(text)

            # Assert that the result matches the expected sentence tokenization
            self.assertEqual(result, expected_result)

        except Exception as e:
            print("An error occurred:", str(e))
            raise
    def test_word_tokenize_text(self):
        try:
            # Example text
            text = "This is a sentence."

            # Call the word_tokenize_text function with the defined text
            result = text_analysis.word_tokenize_text(text)

            # Expected result using NLTK's word_tokenize function
            expected_result = word_tokenize(text)

            # Assert that the result matches the expected word tokenization
            self.assertEqual(result, expected_result)

        except Exception as e:
            print("An error occurred:", str(e))
            raise

    def test_pos_tag_text(self):
        try:
            # Example tokens
            tokens = ["apple", "banana", "orange"]

            # Mocking pos_tag to return dummy values
            with patch('nltk.tag.pos_tag', return_value=[('apple', 'NN'), ('banana', 'NN'), ('orange', 'NN')]):
                result = pos_tag_text(tokens)

            # Assert that the result matches the mocked return value
            self.assertEqual(result, [('apple', 'NN'), ('banana', 'NN'), ('orange', 'NN')])

        except Exception as e:
            print("An error occurred:", str(e))
            raise

    def test_freq_dist_text(self):
        try:
            # Example tokens
            tokens = ["apple", "banana", "apple", "orange", "banana", "apple"]

            # Call the freq_dist_text function with the defined tokens
            result = text_analysis.freq_dist_text(tokens)

            # Expected result using NLTK's FreqDist class
            expected_freq_dist = FreqDist(tokens)

            # Assert that the result matches the expected frequency distribution
            self.assertEqual(result, expected_freq_dist)

        except Exception as e:
            print("An error occurred:", str(e))
            raise
    def test_wordnet_lemmatizer(self):
        try:
            # Call the wordnet_lemmatizer function
            result = text_analysis.wordnet_lemmatizer()

            # Assert that the result is an instance of WordNetLemmatizer
            self.assertIsInstance(result, WordNetLemmatizer)

        except Exception as e:
            print("An error occurred:", str(e))
            raise


# -*- coding: utf-8 -*-
"""Tests using pytest_resilient_circuits"""

from __future__ import print_function
import pytest
from mock_attachment import AttachmentMock
from resilient_circuits.util import get_config_data, get_function_definition
from resilient_circuits import SubmitTestFunction, FunctionResult

PACKAGE_NAME = "fn_utilities"
FUNCTION_NAME = "utilities_pdfid"

# Read the default configuration-data section from the package
config_data = get_config_data(PACKAGE_NAME)

# Provide a simulation of the SOAR REST API (uncomment to connect to a real appliance)
resilient_mock = AttachmentMock

SAMPLE1_RESULTS = {
    "header": "%PDF-1.3",
    "isPdf": "True",
    "obj": 20,
    "endobj": 20,
    "stream": 3,
    "endstream": 3,
    "xref": 1,
    "trailer": 1,
    "startxref": 1,
    "/Page": 1,
    "/Encrypt": 0,
    "/ObjStm": 0,
    "/JS": 0,
    "/JavaScript": 0,
    "/AA": 0,
    "/OpenAction": 0,
    "/AcroForm": 0,
    "/JBIG2Decode": 0,
    "/RichMedia": 0,
    "/Launch": 0,
    "/EmbeddedFile": 0,
    "/XFA": 0,
    "/Colors > 2^24": 0
}

def call_pdfid_function(circuits, function_params, timeout=10):
    # Fire a message to the function
    evt = SubmitTestFunction(FUNCTION_NAME, function_params)
    circuits.manager.fire(evt)
    event = circuits.watcher.wait("{}_result".format(FUNCTION_NAME), parent=evt, timeout=timeout)
    assert event
    assert isinstance(event.kwargs["result"], FunctionResult)
    pytest.wait_for(event, "complete", True)
    return event.kwargs["result"].value

class TestPdfid:
    """ Tests for the pdfid function"""

    def test_function_definition(self):
        """ Test that the package provides customization_data that defines the function """
        func = get_function_definition(PACKAGE_NAME, FUNCTION_NAME)
        assert func is not None

    @pytest.mark.parametrize("base64content, expected_results", [
        (AttachmentMock.test_data_b64("sample1.pdf"), SAMPLE1_RESULTS)
    ])
    def test_success(self, circuits_app, base64content, expected_results):
        """ Test calling with sample values for the parameters """
        function_params = {
            "base64content": base64content
        }
        results = call_pdfid_function(circuits_app, function_params)
        assert(expected_results == results)


def solution(n):
    answer = 0

    dp = [0] * (1+n)
    if n == 1:
        return 1

    dp[1] = 1
    dp[2] = 2

    if n >= 3:
        for i in range(3, n+1):
            dp[i] = (dp[i-1] + dp[i-2]) % 1234567

    answer = dp[n] % 1234567
    return answer


# Method-2 Reverse linkedList

def isPalindrome(head):
    slow = fast = head

    while fast and fast.next:
        fast = fast.next.next
        slow = slow.next
    node = None
    while slow:
        nxt = slow.next
        slow.next = node
        node =  slow
        slow = nxt

    while node:
        if node.val != head.val:
            return False
        node =node.next
        head = head.next
    return True

# Time Complexity : O(n)
# Space Complexity : O(n)


#!/usr/bin/python
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

browser = webdriver.Firefox()
browser.get("http://localhost:5000/")
time.sleep(3) # Let the user actually see something!

search = browser.find_element_by_name("search")
search.send_keys("the shining")

search.submit()

time.sleep(5)
browser.close()


import torch
import torch.nn as nn
import torch.optim as optim

class TrainWrapperBaseClass():
    def __init__(self, args, config) -> None:
        self.init_optimizer()

    def init_optimizer(self) -> None:
        print('using Adam')
        self.generator_optimizer = optim.Adam(
            self.generator.parameters(),
            lr = self.config.Train.learning_rate.generator_learning_rate,
            betas=[0.9, 0.999]
        )
        if self.discriminator is not None:
            self.discriminator_optimizer = optim.Adam(
                self.discriminator.parameters(),
                lr = self.config.Train.learning_rate.discriminator_learning_rate,
                betas=[0.9, 0.999]
            )

    def __call__(self, bat):
        raise NotImplementedError

    def get_loss(self, **kwargs):
        raise NotImplementedError

    def state_dict(self):
        model_state = {
            'generator': self.generator.state_dict(),
            'generator_optim': self.generator_optimizer.state_dict(),
            'discriminator': self.discriminator.state_dict() if self.discriminator is not None else None,
            'discriminator_optim': self.discriminator_optimizer.state_dict() if self.discriminator is not None else None
        }
        return model_state

    def parameters(self):
        return self.generator.parameters()

    def load_state_dict(self, state_dict):
        if 'generator' in state_dict:
            self.generator.load_state_dict(state_dict['generator'])
        else:
            self.generator.load_state_dict(state_dict)

        if 'generator_optim' in state_dict and self.generator_optimizer is not None:
            self.generator_optimizer.load_state_dict(state_dict['generator_optim'])

        if self.discriminator is not None:
            self.discriminator.load_state_dict(state_dict['discriminator'])

            if 'discriminator_optim' in state_dict and self.discriminator_optimizer is not None:
                self.discriminator_optimizer.load_state_dict(state_dict['discriminator_optim'])

    def infer_on_audio(self, aud_fn, initial_pose=None, norm_stats=None, **kwargs):
        raise NotImplementedError

    def init_params(self):
        if self.config.Data.pose.convert_to_6d:
            scale = 2
        else:
            scale = 1

        global_orient = round(0 * scale)
        leye_pose = reye_pose = round(0 * scale)
        jaw_pose = round(0 * scale)
        body_pose = round((63 - 24) * scale)
        left_hand_pose = right_hand_pose = round(45 * scale)
        if self.expression:
            expression = 100
        else:
            expression = 0

        b_j = 0
        jaw_dim = jaw_pose
        b_e = b_j + jaw_dim
        eye_dim = leye_pose + reye_pose
        b_b = b_e + eye_dim
        body_dim = global_orient + body_pose
        b_h = b_b + body_dim
        hand_dim = left_hand_pose + right_hand_pose
        b_f = b_h + hand_dim
        face_dim = expression

        self.dim_list = [b_j, b_e, b_b, b_h, b_f]
        self.full_dim = jaw_dim + eye_dim + body_dim + hand_dim
        self.pose = int(self.full_dim / round(3 * scale))
        self.each_dim = [jaw_dim, eye_dim + body_dim, hand_dim, face_dim]


import pytest

from snapcraft_legacy.storeapi.v2 import validation_sets

@pytest.mark.parametrize("snap_id", (None, "snap_id"))
@pytest.mark.parametrize("presence", (None, "required", "optional", "invalid"))
@pytest.mark.parametrize("revision", ("42", None))
def test_snap(snap_id, presence, revision):
    payload = {
        "name": "set-1",
    }

    if presence is not None:
        payload["presence"] = presence

    if snap_id is not None:
        payload["id"] = snap_id

    if revision is not None:
        payload["revision"] = revision

    s = validation_sets.Snap.unmarshal(payload)

    assert repr(s) == "<Snap: 'set-1'>"
    assert s.name == payload["name"]
    assert s.snap_id == payload.get("id")
    assert s.presence == payload.get("presence")
    assert s.revision == payload.get("revision")
    assert s.marshal() == payload

@pytest.mark.parametrize("revision", ("42", None))
def test_build_assertion(revision):
    payload = {
        "account-id": "account-id-1",
        "authority-id": "authority-id-1",
        "name": "validation-set-1",
        "sequence": "1",
        "series": "16",
        "snaps": [validation_sets.Snap(name="snap-name").marshal()],
        "timestamp": "2020-10-29T16:36:56Z",
        "type": "validation-set",
    }

    if revision is not None:
        payload["revision"] = revision

    s = validation_sets.BuildAssertion.unmarshal(payload)

    assert repr(s) == "<BuildAssertion: 'validation-set-1'>"
    assert s.account_id == payload["account-id"]
    assert s.authority_id == payload["authority-id"]
    assert s.name == payload["name"]
    assert s.sequence == payload.get("sequence")
    assert s.series == payload.get("series")
    assert s.snaps == [validation_sets.Snap(name="snap-name")]
    assert s.timestamp == "2020-10-29T16:36:56Z"

    if revision is None:
        payload["revision"] = "0"

    assert s.marshal() == payload

def test_validation_sets():
    payload = {
        "assertions": [
            {
                "headers": {
                    "account-id": "account-id-1",
                    "authority-id": "authority-id-1",
                    "name": "validation-set-1",
                    "revision": "1",
                    "sequence": "1",
                    "series": "16",
                    "snaps": [validation_sets.Snap(name="snap-name-1").marshal()],
                    "timestamp": "2020-10-29T16:36:56Z",
                    "type": "validation-set",
                }
            },
            {
                "headers": {
                    "account-id": "account-id-1",
                    "authority-id": "authority-id-1",
                    "name": "validation-set-1",
                    "revision": "3",
                    "sequence": "1",
                    "series": "16",
                    "snaps": [validation_sets.Snap(name="snap-name-2").marshal()],
                    "timestamp": "2020-10-29T16:36:56Z",
                    "type": "validation-set",
                },
            },
        ]
    }

    s = validation_sets.ValidationSets.unmarshal(payload)

    assert repr(s) == "<ValidationSets: assertions 2>"
    assert s.assertions[0] == validation_sets.BuildAssertion.unmarshal(
        {
            "account-id": "account-id-1",
            "authority-id": "authority-id-1",
            "name": "validation-set-1",
            "revision": "1",
            "sequence": "1",
            "series": "16",
            "snaps": [validation_sets.Snap(name="snap-name-1").marshal()],
            "timestamp": "2020-10-29T16:36:56Z",
            "type": "validation-set",
        },
    )

    assert s.assertions[1] == validation_sets.BuildAssertion.unmarshal(
        {
            "account-id": "account-id-1",
            "authority-id": "authority-id-1",
            "name": "validation-set-1",
            "revision": "3",
            "sequence": "1",
            "series": "16",
            "snaps": [validation_sets.Snap(name="snap-name-2").marshal()],
            "timestamp": "2020-10-29T16:36:56Z",
            "type": "validation-set",
        }
    )

    assert s.marshal() == payload


from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException, Body

from crud.users import user_crud, client_crud
from dependencies import get_db
from sqlalchemy.orm import Session

from schemas.users import ClientCreate, Client

router = APIRouter(
    prefix="/clients",
    tags=["clients"],
    responses={404: {"description": "Not found"}},
)

@router.post("/", response_model=Client)
def write_client(client: ClientCreate, db: Session = Depends(get_db)):
    db_client = user_crud.get_user_by_email(db, email=client.user.email)
    if db_client:
        raise HTTPException(status_code=400, detail="Email already registered")
    return client_crud.create(db=db, client=client)

@router.get("/", response_model=list[Client])
def read_clients(offset: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    clients = client_crud.get_many(db, offset=offset, limit=limit)
    return clients

@router.get("/{client_id}", response_model=Client)
def read_client(client_id: UUID, db: Session = Depends(get_db)):
    db_client = client_crud.get(db, client_id=client_id)
    if db_client is None:
        raise HTTPException(status_code=404, detail="Client not found")
    return db_client

@router.post("/{client_id}/set-coach", response_model=Client)
def set_coach(client_id: UUID, coach_id: UUID = Body(embed=True), db: Session = Depends(get_db)):
    return client_crud.set_client_coach(db, client_id=client_id, coach_id=coach_id)


import argparse
import enum
import json
import os
import sys
import traceback
import unittest
from types import TracebackType
from typing import Dict, List, Optional, Tuple, Type, TypeAlias, TypedDict

# Add the path to pythonFiles to sys.path to find testing_tools.socket_manager.
PYTHON_FILES = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, PYTHON_FILES)
# Add the lib path to sys.path to find the typing_extensions module.
sys.path.insert(0, os.path.join(PYTHON_FILES, "lib", "python"))
from testing_tools import socket_manager
from typing_extensions import NotRequired
from unittestadapter.utils import parse_unittest_args

DEFAULT_PORT = "45454"

def parse_execution_cli_args(args: List[str]) -> Tuple[int, str | None, List[str]]:
    """Parse command-line arguments that should be processed by the script.

    So far this includes the port number that it needs to connect to, the uuid passed by the TS side,
    and the list of test ids to report.
    The port is passed to the execution.py script when it is executed, and
    defaults to DEFAULT_PORT if it can't be parsed.
    The list of test ids is passed to the execution.py script when it is executed, and defaults to an empty list if it can't be parsed.
    The uuid should be passed to the execution.py script when it is executed, and defaults to None if it can't be parsed.
    If the arguments appear several times, the value returned by parse_cli_args will be the value of the last argument.
    """
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument("--port", default=DEFAULT_PORT)
    arg_parser.add_argument("--uuid")
    arg_parser.add_argument("--testids", nargs="+")
    parsed_args, _ = arg_parser.parse_known_args(args)

    return (int(parsed_args.port), parsed_args.uuid, parsed_args.testids)

ErrorType = (
    Tuple[Type[BaseException], BaseException, TracebackType] | Tuple[None, None, None]
)

class TestOutcomeEnum(str, enum.Enum):
    error = "error"
    failure = "failure"
    success = "success"
    skipped = "skipped"
    expected_failure = "expected-failure"
    unexpected_success = "unexpected-success"
    subtest_success = "subtest-success"
    subtest_failure = "subtest-failure"

class UnittestTestResult(unittest.TextTestResult):
    formatted: Dict[str, Dict[str, str | None]] = dict()

    def startTest(self, test: unittest.TestCase):
        super(UnittestTestResult, self).startTest(test)

    def addError(
        self,
        test: unittest.TestCase,
        err: ErrorType,
    ):
        super(UnittestTestResult, self).addError(test, err)
        self.formatResult(test, TestOutcomeEnum.error, err)

    def addFailure(
        self,
        test: unittest.TestCase,
        err: ErrorType,
    ):
        super(UnittestTestResult, self).addFailure(test, err)
        self.formatResult(test, TestOutcomeEnum.failure, err)

    def addSuccess(self, test: unittest.TestCase):
        super(UnittestTestResult, self).addSuccess(test)
        self.formatResult(test, TestOutcomeEnum.success)

    def addSkip(self, test: unittest.TestCase, reason: str):
        super(UnittestTestResult, self).addSkip(test, reason)
        self.formatResult(test, TestOutcomeEnum.skipped)

    def addExpectedFailure(self, test: unittest.TestCase, err: ErrorType):
        super(UnittestTestResult, self).addExpectedFailure(test, err)
        self.formatResult(test, TestOutcomeEnum.expected_failure, err)

    def addUnexpectedSuccess(self, test: unittest.TestCase):
        super(UnittestTestResult, self).addUnexpectedSuccess(test)
        self.formatResult(test, TestOutcomeEnum.unexpected_success)

    def addSubTest(
        self, test: unittest.TestCase, subtest: unittest.TestCase, err: ErrorType | None
    ):
        super(UnittestTestResult, self).addSubTest(test, subtest, err)
        self.formatResult(
            test,
            TestOutcomeEnum.subtest_failure if err else TestOutcomeEnum.subtest_success,
            err,
            subtest,
        )

    def formatResult(
        self,
        test: unittest.TestCase,
        outcome: str,
        error: ErrorType | None = None,
        subtest: unittest.TestCase | None = None,
    ):
        tb = None
        if error and error[2] is not None:
            # Format traceback
            formatted = traceback.format_exception(*error)
            # Remove the 'Traceback (most recent call last)'
            formatted = formatted[1:]
            tb = "".join(formatted)

        test_id = test.id()

        result = {
            "test": test.id(),
            "outcome": outcome,
            "message": str(error),
            "traceback": tb,
            "subtest": subtest.id() if subtest else None,
        }

        self.formatted[test_id] = result

class TestExecutionStatus(str, enum.Enum):
    error = "error"
    success = "success"

TestResultTypeAlias: TypeAlias = Dict[str, Dict[str, str | None]]

class PayloadDict(TypedDict):
    cwd: str
    status: TestExecutionStatus
    result: NotRequired[TestResultTypeAlias]
    not_found: NotRequired[List[str]]
    error: NotRequired[str]

# Args: start_path path to a directory or a file, list of ids that may be empty.
# Edge cases:
# - if tests got deleted since the VS Code side last ran discovery and the current test run,
# return these test ids in the "not_found" entry, and the VS Code side can process them as "unknown";
# - if tests got added since the VS Code side last ran discovery and the current test run, ignore them.
def run_tests(
    start_dir: str,
    test_ids: List[str],
    pattern: str,
    top_level_dir: Optional[str],
    uuid: Optional[str],
) -> PayloadDict:
    cwd = os.path.abspath(start_dir)
    status = TestExecutionStatus.error
    error = None
    payload: PayloadDict = {"cwd": cwd, "status": status}

    try:
        # If it's a file, split path and file name.
        start_dir = cwd
        if cwd.endswith(".py"):
            start_dir = os.path.dirname(cwd)
            pattern = os.path.basename(cwd)

        # Discover tests at path with the file name as a pattern (if any).
        loader = unittest.TestLoader()

        args = {
            "start_dir": start_dir,
            "pattern": pattern,
            "top_level_dir": top_level_dir,
        }
        suite = loader.discover(start_dir, pattern, top_level_dir)

        # Run tests.
        runner = unittest.TextTestRunner(resultclass=UnittestTestResult)
        # lets try to tailer our own suite so we can figure out running only the ones we want
        loader = unittest.TestLoader()
        tailor: unittest.TestSuite = loader.loadTestsFromNames(test_ids)
        result: UnittestTestResult = runner.run(tailor)  # type: ignore

        payload["result"] = result.formatted

    except Exception:
        status = TestExecutionStatus.error
        error = traceback.format_exc()

    if error is not None:
        payload["error"] = error

    payload["status"] = status

    # print(f"payload: \n{json.dumps(payload, indent=4)}")

    return payload

if __name__ == "__main__":
    # Get unittest test execution arguments.
    argv = sys.argv[1:]
    index = argv.index("--udiscovery")

    start_dir, pattern, top_level_dir = parse_unittest_args(argv[index + 1 :])

    # Perform test execution.
    port, uuid, testids = parse_execution_cli_args(argv[:index])
    payload = run_tests(start_dir, testids, pattern, top_level_dir, uuid)

    # Build the request data (it has to be a POST request or the Node side will not process it), and send it.
    addr = ("localhost", port)
    with socket_manager.SocketManager(addr) as s:
        data = json.dumps(payload)
        request = f"""POST / HTTP/1.1
Host: localhost:{port}
Content-Length: {len(data)}
Content-Type: application/json
Request-uuid: {uuid}

{data}"""
        result = s.socket.sendall(request.encode("utf-8"))  # type: ignore


#!/usr/bin/env python3

import logging
import os
import sys
import utils.mojo_os_utils as mojo_os_utils
import argparse

from zaza.openstack.utilities import (
    cli as cli_utils,
    openstack as openstack_utils,
)

FLAVORS = {
    'm1.tiny': {
        'flavorid': 1,
        'ram': 512,
        'disk': 1,
        'vcpus': 1},
    'm1.small': {
        'flavorid': 2,
        'ram': 2048,
        'disk': 10,
        'vcpus': 1},
    'm1.medium': {
        'flavorid': 3,
        'ram': 4096,
        'disk': 20,
        'vcpus': 2},
    'm1.large': {
        'flavorid': 4,
        'ram': 8192,
        'disk': 20,
        'vcpus': 4},
}

def init_flavors(nova_client):
    logging.info("Initializing flavors if necessary")
    names = [flavor.name for flavor in nova_client.flavors.list()]
    for flavor in FLAVORS.keys():
        if flavor not in names:
            nova_client.flavors.create(
                name=flavor,
                ram=FLAVORS[flavor]['ram'],
                vcpus=FLAVORS[flavor]['vcpus'],
                disk=FLAVORS[flavor]['disk'],
                flavorid=FLAVORS[flavor]['flavorid'])

def main(argv):
    cli_utils.setup_logging()
    parser = argparse.ArgumentParser()
    default_machines = ["cirros:m1.tiny:1"]
    parser.add_argument("machines", default=default_machines, nargs="*")
    parser.add_argument("--active_wait", default=600)
    parser.add_argument("--cloudinit_wait", default=600)
    parser.add_argument("--ping_wait", default=600)
    options = parser.parse_args()
    machines = cli_utils.parse_arg(options, 'machines', multiargs=True)
    active_wait = int(cli_utils.parse_arg(options, 'active_wait'))
    cloudinit_wait = int(cli_utils.parse_arg(options, 'cloudinit_wait'))
    ping_wait = int(cli_utils.parse_arg(options, 'ping_wait'))
    overcloud_novarc = openstack_utils.get_overcloud_auth()
    try:
        cacert = os.path.join(os.environ.get('MOJO_LOCAL_DIR'), 'cacert.pem')
        os.stat(cacert)
        logging.info("Using cacert file: {}".format(cacert))
    except FileNotFoundError:
        logging.info("Not using a cacert pem file")
        cacert = None

    logging.info("Initializing client sessions")
    keystone_session = openstack_utils.get_overcloud_keystone_session(
        verify=cacert)
    keystonec = openstack_utils.get_keystone_session_client(
        keystone_session)
    domain = overcloud_novarc.get('OS_PROJECT_DOMAIN_NAME')
    project_id = openstack_utils.get_project_id(
        keystonec,
        'admin',
        api_version=overcloud_novarc['API_VERSION'],
        domain_name=domain
    )
    novac = openstack_utils.get_nova_session_client(keystone_session)
    neutronc = openstack_utils.get_neutron_session_client(keystone_session)

    init_flavors(novac)

    priv_key = mojo_os_utils.create_keypair(novac, 'mojo')
    openstack_utils.add_neutron_secgroup_rules(neutronc, project_id)
    for server in novac.servers.list(search_opts={'all_tenants': 1}):
        if server.name.startswith('mojo'):
            logging.info("Deleting nova instance {}".format(server.id))
            novac.servers.delete(server.id)
    for instanceset in machines:
        image_name, flavor_name, count = instanceset.split(":")
        # when instance count allows boot instances off both regular instance
        # storage and volume storage
        #
        # account for count=1 and odd numbers

        # NOTE(fnordahl) temporarilly disable test while tests settle
        # regular_boot_count = int(int(count) / 2) + (int(count) % 2)
        # volume_boot_count = int(int(count) / 2)
        regular_boot_count = int(count)
        volume_boot_count = 0
        mojo_os_utils.boot_and_test(novac, neutronc,
                                    image_name=image_name,
                                    flavor_name=flavor_name,
                                    number=regular_boot_count,
                                    privkey=priv_key,
                                    active_wait=active_wait,
                                    cloudinit_wait=cloudinit_wait,
                                    ping_wait=ping_wait,
                                    )
        mojo_os_utils.boot_and_test(novac, neutronc,
                                    image_name=image_name,
                                    flavor_name=flavor_name,
                                    number=volume_boot_count,
                                    privkey=priv_key,
                                    active_wait=active_wait,
                                    cloudinit_wait=cloudinit_wait,
                                    ping_wait=ping_wait,
                                    boot_from_volume=True,
                                    )

if __name__ == "__main__":
    sys.exit(main(sys.argv))


import os

from flask import Flask, render_template, jsonify
from flask_jwt_extended import JWTManager
from flask_restful import Api
from flask_cors import CORS, cross_origin
from Resources.UserRegister import *
from blacklist import BLACKLIST
from db import db as db
# from SETTINGS import uri, secret_key
# from models import CardsModel

app = Flask(__name__)
cors = CORS(app)
cross_origin()
uri = os.environ.get('uri')
secret_key = os.environ.get('secret_key')
# uri = 'sqlite:///data.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = uri
app.config['PROPAGATE_EXCEPTIONS'] = True
api = Api(app)
db.init_app(app)
app.secret_key = secret_key

@app.before_first_request
def create_tables():
    db.create_all()

@app.route('/')
def hello_world():
    return render_template('index.html')

"""
JWT related configuration. The following functions includes:
1) add claims to each jwt
2) customize the token expired error message
"""
# we can also use app.secret like before, Flask-JWT-Extended can recognize both
app.config['JWT_BLACKLIST_ENABLED'] = True  # enable blacklist feature
app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access', 'refresh']  # allow blacklisting for access and refresh tokens
jwt = JWTManager(app)

"""
`claims` are data we choose to attach to each jwt payload
and for each jwt protected endpoint, we can retrieve these claims via `get_jwt_claims()`
one possible use case for claims are access level control, which is shown below
"""
@jwt.user_claims_loader
def add_claims_to_jwt(identity):
    if identity == 1:   # instead of hard-coding, we should read from a config file to get a list of admins instead
        return {'is_admin': True}
    return {'is_admin': False}

# This method will check if a token is blacklisted, and will be called automatically when blacklist is enabled
@jwt.token_in_blacklist_loader
def check_if_token_in_blacklist(decrypted_token):
    return decrypted_token['jti'] in BLACKLIST

# The following callbacks are used for customizing jwt response/error messages.
# The original ones may not be in a very pretty format (opinionated)
@jwt.expired_token_loader
def expired_token_callback():
    return jsonify({
        'message': 'The token has expired.',
        'error': 'token_expired'
    }), 401

@jwt.invalid_token_loader
def invalid_token_callback(error):  # we have to keep the argument here, since it's passed in by the caller internally
    return jsonify({
        'message': 'Signature verification failed.',
        'error': 'invalid_token'
    }), 401

@jwt.unauthorized_loader
def missing_token_callback(error):
    return jsonify({
        "description": "Request does not contain an access token.",
        'error': 'authorization_required'
    }), 401

@jwt.needs_fresh_token_loader
def token_not_fresh_callback():
    return jsonify({
        "description": "The token is not fresh.",
        'error': 'fresh_token_required'
    }), 401

@jwt.revoked_token_loader
def revoked_token_callback():
    return jsonify({
        "description": "The token has been revoked.",
        'error': 'token_revoked'
    }), 401

# JWT configuration ends
api.add_resource(UserRegister, '/register')
api.add_resource(UserLogin, '/login')
api.add_resource(AddCards, '/cards')
api.add_resource(RemoveCards, '/deleteCards')
if __name__ == '__main__':
    db.init_app(app)
    app.run()


import csv, sys

def main():
    if len(sys.argv) != 2:
        return

    in_name = sys.argv[1]

    with open(in_name, mode='rw') as read_file:
        reader = csv.DictReader(read_file)
        tweets = []

        for row in reader:
            data = {}
            data['Id'] = row['inst#']
            data['Expected'] = 1 if (row['predicted']) == "1:Bot" else 0
            tweets.append(data)

        with open(in_name, 'w') as csvFile:
            writer = csv.DictWriter(csvFile, tweets[0].keys())
            writer.writeheader()

            for tweet in tweets:
                writer.writerow(tweet)

if __name__ == '__main__':
    main()


import pandas as pd
from pandas import Series,DataFrame
obj=pd.Series([4,7,-5,3])
obj

obj.values

obj.index

obj2=pd.Series([4,7,-5,3],index=['d','b','a','c'])
obj2

obj2.index
obj2['a']
obj2['d']=6
obj2[['c','a','d']]

obj2[obj2>0]

obj2*2

np.exp(obj2)

'b' in obj2

'e' in obj2

sdata={'Ohio':35000,'Texas':71000,'Oregon':16000,'Utah':5000}
obj3=pd.Series(sdata)
obj3

states=['California','Ohio','Oregon','Texas']
obj4=pd.Series(sdata,index=states)
obj4

pd.isnull(obj4)
pd.notnull(obj4)
obj4.isnull()

obj3
obj4
obj3+obj4

obj4.name='population'
obj4.index.name='state'
obj4

obj
obj.index=['Bob','Steve','Jeff','Ryan']

data={'state':['Ohio','Ohio','Ohio','Nevada','Nevada','Nevada'],
      'year':[2000,2001,2002,2001,2002,2003],
      'pop':[1.5,1.7,3.6,2.4,2.9,3.2]}
frame=pd.DataFrame(data)
frame

frame.head()
pd.DataFrame(data,columns=['year','state','pop'])

frame2=pd.DataFrame(data,columns=['year','state','pop','debt'],
                    index=['one','two','three','four','five','six'])
frame2
frame2.columns

frame2['state']

frame2.year

frame2['year']

frame2.loc['three']

frame2['debt']=16.5

frame2

frame2['debt']=np.arange(6.)
frame2

val=pd.Series([-1.2,-1.5,-1.7],index=['two','four','five'])
frame2['debt']=val
frame2

frame2['eastern']=frame2.state=='Ohio'
frame2

del frame2['eastern']
frame2.columns

pop={'Nevada':{2001:2.4,2002:2.9},'Ohio':{2000:1.5,2001:1.7,2002:3.6}}

frame3=pd.DataFrame(pop)
frame3

frame3.T
label=pd.Index([2001,2002,2003])
#index=np.array([2001,2002,2003],dtype=np.int64)
pd.DataFrame(pop,index=label)

pdata={'Ohio':frame3['Ohio'][:-1],
       'Nevada':frame3['Nevada'][:2]}

pd.DataFrame(pdata)

frame3.index.name='year';frame3.columns.name='state'
frame3

frame3.values

frame2.values

obj=pd.Series(range(3),index=['a','b','c'])
index=obj.index
index
index[1:]
#index[1]='d'
labels=pd.Index(np.arange(3))
labels
obj2=pd.Series([1.5,-2.5,0],index=labels)
obj2

obj2.index is labels

frame3

frame3.columns

'Ohio' in frame3.columns
'Ohio' in frame3.index

dup_labels=pd.Index(['foo','foo','bar','bar'])
dup_labels

obj=pd.Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c'])
obj

obj2=obj.reindex(['a','b','c','d','e'])
obj2

obj3=pd.Series(['blue','purple','yellow'],index=[0,2,4])
obj3

obj3.reindex(range(6),method='ffill')

frame=pd.DataFrame(np.arange(9).reshape((3,3)),
                   index=['a','c','d'],
                   columns=['Ohio','Texas','California'])
frame2=frame.reindex(['a','b','c','d'])
frame2

states=['Texas','Utah','California']

frame.reindex(columns=states)

frame.loc[['a','b','c','d'],states]

obj=pd.Series(np.arange(5.),index=['a','b','c','d','e'])
obj
new_obj=obj.drop('c')
new_obj
obj.drop(['d','c'])

data=pd.DataFrame(np.arange(16).reshape((4,4)),
                  index=['Ohio','Colorado','Utah','New York'],
                  columns=['one','two','three','four'])
data

data.drop(['Colorado','Ohio'])

data.drop('two',axis=1)
data.drop(['two','four'],axis='columns')

obj.drop('c',inplace=True)

obj=pd.Series(np.arange(4.),index=['a','b','c','d'])
obj

obj['b']
obj[1]

obj[2:4]
obj[['b','a','d']]

obj[[1,3]]

obj[obj<2]

obj['b':'c']

obj['b':'c']=5
obj

data=pd.DataFrame(np.arange(16).reshape((4,4)),
                  index=['Ohio','Colorado','Utah','New York'],
                  columns=['one','two','three','four'])

data
data['two']
data[['three','four']]
data[:2]
data[data['three']>5]

data<5

data[data<5]=0
data

data.loc['Colorado',['two','three']]

data.iloc[2,[3,0,1]]

data.iloc[2]
data.iloc[[1,2],[3,0,1]]
data.loc[:'Utah','two']
data.iloc[:,:3][data.three>5]

ser=pd.Series(np.arange(3.))
ser
#ser[-1]
ser2=pd.Series(np.arange(3.),index=['a','b','c'])
ser2[-1]

ser[:1]
ser.loc[:1]
ser.iloc[:1]

s1=pd.Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e'])
s2=pd.Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g'])
s1
s2
s1+s2

df1=pd.DataFrame(np.arange(9.).reshape((3,3)),
                 columns=list('bcd'),
                 index=['Ohio','Texas','Colorado'])
df2=pd.DataFrame(np.arange(12.).reshape((4,3)),
                 columns=list('bde'),
                 index=['Utah','Ohio','Texas','Oregon'])
df1
df2
df1+df2

df1=pd.DataFrame({'A':[1,2]})
df2=pd.DataFrame({'B':[3,4]})
df1
df2
df1-df2

df1=pd.DataFrame(np.arange(12.).reshape((3,4)),
                 columns=list('abcd'))
df2=pd.DataFrame(np.arange(20.).reshape((4,5)),
                 columns=list('abcde'))
df2.loc[1,'b']=np.nan
df1
df2
df1+df2

df1.add(df2,fill_value=0)

1/df1

df1.rdiv(1)
df1.reindex(columns=df2.columns,fill_value=0)

arr=np.arange(12.).reshape((3,4))
arr
arr[0]
arr-arr[0]

frame=pd.DataFrame(np.arange(12.).reshape((4,3)),
                   columns=list('bde'),
                   index=['Utah','Ohio','Texas','Oregon'])
frame
series=frame.iloc[0]

series

frame-series

series2=pd.Series(range(3),index=['b','e','f'])
frame+series2
series3=frame['d']

frame
series3
frame.sub(series3,axis='index')

frame=pd.DataFrame(np.random.randn(4,3),columns=list('bde'),
                   index=['Utah','Ohio','Texas','Oregon'])
frame

np.abs(frame)

f=lambda x:x.max()-x.min()
frame.apply(f)

frame.apply(f,axis=1)

def f(x):
    return pd.Series([x.min(),x.max()],index=['min','max'])

frame.apply(f)

format=lambda x:'%.2f' % x
frame.applymap(format)

frame['e'].map(format)

obj=pd.Series(range(4),index=['d','a','b','c'])

frame=pd.DataFrame(np.arange(8).reshape((2,4)),
                   index=['three','one'],
                   columns=['d','a','b','c'])
frame.sort_index()

frame.sort_index(axis=1)

frame.sort_index(axis=1,ascending=False)

obj=pd.Series([4,7,-3,2])
obj.sort_values()

obj=pd.Series([4,np.nan,7,np.nan,-3,2])
obj.sort_values()

frame=pd.DataFrame({'b':[4,7,-3,2],'a':[0,1,0,1]})
frame

frame.sort_values(by='b')

frame.sort_values(by=['a','b'])

obj=pd.Series([7,-5,7,4,2,0,4])
obj.rank()

obj.rank(method='first')

obj.rank(ascending=False,method='max')

frame=pd.DataFrame({'b':[4.3,7,-3,2],'a':[0,1,0,1],'c':[-2,5,8,-2.5]})

frame
frame.rank(axis='columns')

obj=pd.Series(range(5),index=['a','a','b','b','c'])
obj

obj.index.is_unique

obj['a']

obj['c']

df=pd.DataFrame(np.random.randn(4,3),index=['a','a','b','b'])
df
df.loc['b']

df=pd.DataFrame([[1.4,np.nan],[7.1,-4.5],[np.nan,np.nan],[0.75,-1.3]],
                index=['a','b','c','d'],columns=['one','two'])

df.sum()

df.sum(axis=1)

df.mean(axis='columns',skipna=False)

df.idxmax()
df.cumsum()

df.describe()

obj=pd.Series(['a','a','b','c']*4)

obj.describe()

pd.core.common.is_list_like = pd.api.types.is_list_like
import pandas_datareader.data as web

all_data={ticker:web.get_data_yahoo(ticker) for ticker in ['AAPL','IBM',
                                                           'MSFT','GOOG']}

price = pd.read_pickle('pydata-book-2nd-edition/examples/yahoo_price.pkl')
volume = pd.read_pickle('pydata-book-2nd-edition/examples/yahoo_volume.pkl')

returns=price.pct_change()
returns.tail()

returns.head()

returns['MSFT'].corr(returns['IBM'])
returns['MSFT'].cov(returns['IBM'])

returns.MSFT.corr(returns.IBM)

returns.corr()

returns.cov()

returns.corrwith(returns.IBM)

returns.corrwith(volume)

obj=pd.Series(['c','a','d','a','a','b','b','c','c'])
uniques=obj.unique()
uniques
obj.value_counts()
pd.value_counts(obj.values,sort=False)

mask=obj.isin(['b','c'])
mask
obj[mask]

to_match=pd.Series(['c','a','b','b','c','a'])
unique_vals=pd.Series(['c','b','a'])
pd.Index(unique_vals).get_indexer(to_match)

data=pd.DataFrame({'Qu1':[1,3,4,3,4],
                   'Qu2':[2,3,1,2,3],
                   'Qu3':[1,5,2,4,4]})
data
result=data.apply(pd.value_counts).fillna(0)
result


import matplotlib.pyplot as plt
import numpy as np

log=np.loadtxt('def.txt')

fig,ax1=plt.subplots(dpi=200)
ax1.grid()

lns1=ax1.plot(log[:,0],log[:,-1],c='r',label='Total energy')
ax1.set_ylabel(r"Energy (eV)")

ax2=ax1.twinx()
lns2=ax2.plot(log[:,0],log[:,1]-273.15,c='b',label='Temperature')
ax1.set_xlabel(r"Time (10^-12 sec)")
ax2.set_ylabel(r"Temperature ($^\circ$C)")
lns = lns1+lns2
labs = [l.get_label() for l in lns]
ax1.legend(lns, labs, loc=0,fontsize=20)
plt.tight_layout()
plt.savefig('fig.png')


from django import forms

class ProductAddToCartForm(forms.Form):
    quantity = forms.IntegerField(widget=forms.TextInput(attrs={'size': '2',
                                                                'value': '1', 'class': 'input-small',
                                                                'maxlength': '5'}),
                                  error_messages={'invalid': 'Введите правильное количество'}, min_value=1,
                                  label='Количество')
    product_slug = forms.CharField(widget=forms.HiddenInput())

    def __init__(self, request=None, *args, **kwargs):
        self.request = request
        super(ProductAddToCartForm, self).__init__(*args, **kwargs)

    def clean(self):
        if self.request:
            if not self.request.session.test_cookie_worked():
                raise forms.ValidationError("Cookies должны быть включены")
        return self.cleaned_data