#!/usr/bin/env python3
#############
#           #
#    Bot    #
#           #
#############

# Written badly by ShiftyWizard

#Importing Requirements
import discord
import asyncio
import random
import os
import traceback
import math
import re
from hyphenate import hyphenate_word
import nltk
from nltk.corpus import wordnet
from nltk.sentiment.vader import SentimentIntensityAnalyzer
import urllib.request
import json
import shutil
import base64
import difflib

#Set working directory to file's location
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)

client = discord.Client()
prefix = "."
txtin = ""
txtout = ""
synonyms = []
sid = SentimentIntensityAnalyzer()

#Compile regex for xkcd37
xkcd37 = re.compile(r"(\w)-ass (\w)", re.MULTILINE)
xkcd37sub = "\\1 ass-\\2"

#Make some nice room in the command line
print("")

#Pre-boot settings update
print("|| Updating settings... ")
with open('settings.json','r') as settingsfile:
	master = json.loads(settingsfile.read())
	for file in os.listdir("settings"):
		with open(os.path.join("settings",file),'r+') as serverfile:
			changed=False
			serversettings = json.loads(serverfile.read())
			for command in master['commands'].keys():
				if not command in serversettings['commands'].keys():
					serversettings['commands'][command] = master['commands'][command]
					changed = True
					print("| Command " + command + " added to " + file)
			if changed:
				serverfile.seek(0)# reset file position to the beginning.
				json.dump(serversettings, serverfile, indent=4)
				serverfile.truncate()
			serverfile.close()
	settingsfile.close()
print("|| Settings up to date. ")

#Create the users file if it doesn't exist
if not os.path.isfile('users.json'):
		with open('users.json','w') as userfile:
			userfile.write("{\n}")
			print("Created users.json")

@client.event
async def on_ready():
	#Lists local server files that have no corresponding server
	serverids=[] #Initialize array
	for server in client.servers:
		serverids.append(server.id) #Append server ids to array
	print(serverids)
	print(os.listdir('settings'))
	for file in os.listdir('settings'):
		if not file.split(".")[0] in serverids:
			print(client.user.name + " has been removed from " + file.split(".")[0] + ", or the server no longer exists. ")
	print("")
	############################
	print("Account: "+client.user.name)
	print("Account ID: "+client.user.id)
	print("Bot Account: "+str(client.user.bot))
	print("||||||||| ONLINE |||||||||")
	await client.change_presence(game=discord.Game(name="Use .info for help."))

@client.event
async def on_message(message):
	if client.user.id != message.author.id and not message.author.bot:
		with open('users.json','r+') as userfile:
			users = json.loads(userfile.read())
			if not message.author.id in users.keys():
				users[str(message.author.id)] = {"xp":0,"level":1}

			#Add xp to a user's file based off of message length and a modifier
			users[str(message.author.id)]["xp"] = int(users[str(message.author.id)]["xp"]) + math.floor(len(message.content)/8) + 10
			if int(users[str(message.author.id)]["xp"])>int(users[str(message.author.id)]["level"])*1000:
				print(message.author.name + " just leveled up!")
				users[str(message.author.id)]["level"] = int(users[str(message.author.id)]["level"]) + 1
				users[str(message.author.id)]["xp"] = 0

				embed = discord.Embed(title="Level Up!", description=str(message.author.display_name) + " is now level " + str(users[str(message.author.id)]["level"]) + "!", color=0xbc42f4)
				if message.author.avatar_url:
					embed.set_thumbnail(url=message.author.avatar_url)
				await client.send_message(message.channel, embed=embed)
			userfile.seek(0)
			userfile.truncate(0) #erases file before dumping the new json. Shouldn't have to do this but we're here arn't we
			json.dump(users, userfile, indent=4)

		if not os.path.isfile(os.path.join('settings',str(message.server.id+'.json'))):
			shutil.copy2('settings.json', os.path.join('settings',str(message.server.id+'.json')))
			print("created "+str(os.path.join('settings',str(message.server.id+'.json'))))

		with open(os.path.join('settings',str(message.server.id+'.json')),'r') as serversettings:
			settings = json.loads(serversettings.read())
			prefix = str(settings["bot"]["prefix"])
			global txtout

			#.test#
			if await checkCommand(settings,"test",message):
				print(':robot:')
				await client.send_message(message.channel, ':robot:')

			#.info#
			elif await checkCommand(settings,"info",message):
				print('BOT INFO')
				embed = discord.Embed(title="BOT INFO", description="Made by @ShiftyWizard#4823 & @Arboreal#4200 for fun.", url="https://github.com/leaharboreal/bot", color=0x1abc9c)
				embed.set_thumbnail(url="https://raw.githubusercontent.com/leaharboreal/bot/master/profilepic.png")
				embed.set_footer(text="© bot | 2018", icon_url="https://raw.githubusercontent.com/leaharboreal/bot/master/profilepic.png")
				await client.send_message(message.channel, embed=embed)

			elif message.content.lower().startswith(prefix+settings["commands"]["settings"]["command"]) and message.author.server_permissions.manage_server:
				#upgrade the file's read permissions to rw#
				serversettings.close()
				with open(os.path.join('settings',str(message.server.id+'.json')),'r+') as serversettings:
					#convert the current server's settings.json file into a python object#
					settings = json.loads(serversettings.read())

					#set changed to false so if no setting is modified the file will be unchanged#
					changed=False

					#check if number of args in message is high enough else reply with syntax error#
					if len(message.content.lower().split(" "))>1:

						#check if the first argument is commands#
						if message.content.lower().split(" ")[1]=="commands":

							#check if number of args in message is high enough for this branch#
							if len(message.content.lower().split(" "))>2:

								#ensure the command exists and is not the info or settings command#
								if (message.content.lower().split(" ")[2] in settings["commands"]) and not (message.content.lower().split(" ")[2] in ["info","settings"]):

									#check if number of args in message is high enough for this branch#
									if len(message.content.lower().split(" "))>3 and len(message.content.lower().split(" "))<6:

										#check if the user wants to change the command alias#
										if message.content.lower().split(" ")[3]=="command":

											#ensure the command contains only safe characters and is smaller or equal to 16 characters#
											if re.match(r"^[\w\d~!@#$%^&+=;:,./?\*\-]{1,16}$",message.content.lower().split(" ")[4]):

												#set the selected command to the alias#
												settings["commands"][message.content.lower().split(" ")[2]]["command"]=message.content.lower().split(" ")[4]

												#set changed to true, ensuring the file is saved#
												changed=True

												#set output message to confirmation#
												txtout = message.content.lower().split(" ")[2]+" has been set to "+message.content.lower().split(" ")[4]

											#reject command alias#
											else:
												txtout = "Could not set command. Commands can only 1-16 characters long and contain letters, numbers and these symbols: `~!@#$%^&+=;:,./?*-`"

										#check if the user wants to change if command is enabled#
										elif message.content.lower().split(" ")[3]=="enabled":

											#check if argument is true#
											if message.content.lower().split(" ")[4]=="true":

												#set the commands enabled value to true#
												settings["commands"][message.content.lower().split(" ")[2]]["enabled"]=True

												#set changed to true, ensuring the file is saved#
												changed=True

												#set output message to confirmation#
												txtout = message.content.lower().split(" ")[2]+" is now `enabled`."

											#check if answer is false if not true#
											elif message.content.lower().split(" ")[4]=="false":

												#set the commands enabled value to false#
												settings["commands"][str(message.content.lower().split(" ")[2])]["enabled"]=False

												#set changed to true, ensuring the file is saved#
												changed=True

												#set output message to confirmation#
												txtout = message.content.lower().split(" ")[2]+" is now `disabled`."

											#reject value as it is not true or false#
											else:
												txtout = "This value can only be set to `true` or `false`."
										#unrecognised argument#
										else:
											txtout = "Incorrect syntax(E:2). `"+prefix+"settings commands "+message.content.split(" ")[2]+" <command|enabled> <value>`"
									#not enough args#
									else:
										txtout = "Incorrect syntax (E:1). `"+prefix+"settings commands "+message.content.split(" ")[2]+" <command|enabled> <value>`"
								#unrecognised/locked argument#
								else:
									txtout = "Command `"+message.content.split(" ")[2]+"` not found or cannot be modified. Check the github page command list which can be accessed with `"+prefix+"info`"
							#not enough args#
							else:
								txtout = "Incorrect syntax. `"+prefix+"settings commands <commandname> <command|enabled> <value>`"

						#check if the first argument is bot, if it isn't commands#
						elif message.content.lower().split(" ")[1]=="bot":

							#check if number of args in message is high enough for this branch#
							if len(message.content.lower().split(" "))>2:

								#check if arg is equal to prefix#
								if message.content.lower().split(" ")[2]=="prefix":

									#check if number of args in message is high enough for this branch#
									if len(message.content.lower().split(" "))>3:

										#check if user's value matches rule#
										if re.match(r"^[\w\d~!@#$%^&+=;:,./?\*\-]{1,4}$",message.content.split(" ")[3]):

											#set bot prefix to the user value#
											settings["bot"]["prefix"]=message.content.lower().split(" ")[3]

											#set changed to true, ensuring the file is saved#
											changed=True

											#set output message to confirmation#
											txtout = "Prefix set. Bot will respond to commands with the prefix `"+message.content.lower().split(" ")[3]+"`. To access settings, use the new prefix."

										#reject prefix as it does not conform to the character requirements#
										else:
											txtout = "Could not set prefix. Prefixes can only 1-4 characters long and contain letters, numbers and these symbols: `~!@#$%^&+=;:,./?*-`"

									#not enough args#
									else:
										txtout = "Incorrect syntax. `"+prefix+"settings bot prefix <value>`"

								#incorrect arg#
								else:
									txtout = "Incorrect syntax. `"+prefix+"settings bot prefix <value>`"

							#not enough args#
							else:
								txtout = "Incorrect syntax. `"+prefix+"settings bot prefix <value>`"

						#the first argument is incorrect, so respond with a syntax error#
						else:
							txtout = "Incorrect syntax. `"+prefix+"settings <commands|bot>`"

					#not enough args#
					else:
						txtout = "Incorrect syntax. `"+prefix+"settings <commands|bot>`"

					#if the file has been changed at any point, save changes#
					if changed:
						serversettings.seek(0)# reset file position to the beginning.
						json.dump(settings, serversettings, indent=4)
						serversettings.truncate()

					#log output in console then send as discord message#
					print(txtout)
					await client.send_message(message.channel,txtout)

			#.purge
			elif await checkCommand(settings,"purge",message) and message.server.me.permissions_in(message.channel).manage_messages:
				if message.author.server_permissions.manage_messages and message.author.server_permissions.manage_server:
					if len(message.content.lower().split(" ")) == 2:
						limit = int(message.content.lower().split(" ")[1])
						if limit <= 100:
							if await client.purge_from(message.channel,limit=limit):
								await client.send_message(message.channel, ":warning: Deleted "+str(limit)+" messages.")
						else:
							await client.send_message(message.channel, "100 messages max!")
					else:
						await client.send_message(message.channel, "Please specify the number of messages!")
				else:
					await client.send_message(message.channel, "You need at least manage messages and manage server permissions to do that!")

			#.level#
			elif await checkCommand(settings,"level",message):
				txtout = "Level " + str(users[str(message.author.id)]["level"]) + "\n" + str(users[str(message.author.id)]["xp"]) + " xp"
				embed = discord.Embed(title=str(message.author.display_name), description=txtout, color=0x42b3f4)
				if message.author.avatar_url:
					embed.set_thumbnail(url=message.author.avatar_url)
				await client.send_message(message.channel, embed=embed)

			#.addquote#
			elif await checkCommand(settings,"addquote",message):
				#check if the quotes file exists for the server, if not, create a file with an empty json object#
				if not os.path.isfile(os.path.join('quotes',str(message.server.id+'.json'))):
					with open(os.path.join('quotes',str(message.server.id+'.json')), 'a') as f:
						f.write("{\n}")
				#open the server's quote file#
				with open(os.path.join('quotes',str(message.server.id+'.json')),'r+') as f:
					quotes = json.loads(f.read()) #initialize json file as python object#

					#set quotemessage to the message object before the user's command#
					quotemessage = await getQuote(message)
					quote = base64.b64encode(str(quotemessage.content).encode('utf-8')).decode('utf-8')

					#ensure quote does not contain any illegal symbols#

					if quotemessage.author.id in quotes: #if the user already has a quote object then append quote#
						quoteid = int(max(quotes[quotemessage.author.id].keys()))+1
						quotes[str(quotemessage.author.id)][quoteid] = quote
					else: #if they don't have a quote object, create one with their 1st quote#
						quoteid = 1
						quotes[quotemessage.author.id]={}
						quotes[quotemessage.author.id][quoteid] = quote

					print("Added Quote to file "+message.server.id+".json: "+str(quotemessage.content)) #add log of changes#
					await client.send_message(message.channel,":white_check_mark: Added quote: `"+str(quotemessage.content)+"`") #confirm addition of quote#

					#seek to start of file before dumping the new json object in the file#
					f.seek(0)
					json.dump(quotes, f, indent=4)
					f.close() #close the file since we are done with it#

			#.quote#
			elif await checkCommand(settings,"quote",message):
				if os.path.isfile(os.path.join('quotes',str(message.server.id+'.json'))):
					with open(os.path.join('quotes',str(message.server.id+'.json')),'r') as f:
						quotes = json.loads(f.read())
						if message.mentions:
							if message.mentions[0].id in quotes.keys():
								quoteauthor = message.mentions[0].id
								txtout="```"+base64.b64decode(str(quotes[quoteauthor][random.choice(list(quotes[quoteauthor].keys()))])).decode('utf-8')+"```"+message.mentions[0].mention
							else:
								txtout="Oops! "+message.mentions[0].mention+" hasn't been quoted on this server yet.\nUse `"+prefix+"addquote` when they say something great."
						else:
							quoteauthor = await client.get_user_info(random.choice(list(quotes.keys())))
							txtout="```"+base64.b64decode(str(quotes[quoteauthor.id][random.choice(list(quotes[quoteauthor.id].keys()))])).decode('utf-8')+"```"+quoteauthor.mention
				else:
					txtout="Oops! No quotes available for this server!\nUse `"+prefix+"addquote` to add quotes."
				print(txtout)
				await client.send_message(message.channel,txtout)

			#@SOMEONE#
			elif await checkCommand(settings,"@someone",message,atStart=False):
				x = message.server.members
				members = []
				for member in x:
					if member.permissions_in(message.channel).read_messages and member.permissions_in(message.channel).send_messages:
						members.append(str(member.id))
				someone = random.choice(members)
				print(str(someone) + " was mentioned with @someone by " + str(message.author.id))
				txtout = "<@"+someone+">"+" was randomly mentioned with @someone!"
				await client.send_message(message.channel,txtout)

			#Colour
			elif await checkCommand(settings,"colour",message,atStart=False):
				colour = message.content.lower().split(" ")[1]
				if re.match(r"(^#[\d,a-f]{6}$|^#[\d,a-f]{3}$)",colour):
					colourType = "hex"
					colour = colour[1:]
				elif re.match(r"rgb\((25[0-5]|2[0-4]\d|[0,1]\d\d|\d{1,2}),(25[0-5]|2[0-4]\d|[0,1]\d\d|\d{1,2}),(25[0-5]|2[0-4]\d|[0,1]\d\d|\d{1,2})\)",colour):
					colourType = "rgb"
				elif re.match(r"hsl\((25[0-5]|2[0-4]\d|[0,1]\d\d|\d{1,2}),(100|\d{1,2})%,(100|\d{1,2})%\)",colour):
					colourType = "hsl"
				elif re.match(r"cmyk\((100|\d{1,2}),(100|\d{1,2}),(100|\d{1,2}),(100|\d{1,2})\)",colour):
					colourType = "cmyk"
				else:
					colourType = None
				if colourType:
					print("http://thecolorapi.com/id?"+colourType+"="+colour)
					with urllib.request.urlopen("http://thecolorapi.com/id?"+colourType+"="+colour) as url:
						data = json.loads(url.read().decode())
						colourHEX = data["hex"]["value"]
						colourRGB = data["rgb"]["value"]
						colourHSL = data["hsl"]["value"]
						colourCMYK = data["cmyk"]["value"]
						embed = discord.Embed(title=data["name"]["value"], colour=discord.Colour(int(data["hex"]["value"][1:],16)))
						embed.add_field(name="Hex", value=colourHEX, inline=True)
						embed.add_field(name="RGB", value=colourRGB, inline=True)
						embed.add_field(name="HSL", value=colourHSL, inline=True)
						embed.add_field(name="CMYK", value=colourCMYK, inline=True)
						#embed.set_thumbnail(url=data["image"]["bare"])
						embed.set_footer(text="Sourced using thecolorapi")
						await client.send_message(message.channel, embed=embed)
				else:
					await client.send_message(message.channel,"Format not recognised :(")

			#RETURN STRING WITH SPACES EVERY CHARACTER#
			elif await checkCommand(settings,"widespace",message):
				txtout = ""
				x = ""
				for char in message.content[len(prefix+settings["commands"]["widespace"]["command"]):]:
					if ord(char) in range(33,127):
						x = chr(ord(char)+0xFEE0)
					else:
						x = char
					txtout = txtout + str(x) + " "
				print(txtout)
				await client.send_message(message.channel,txtout)

			#VERBOSE MESSAGE GENERATOR#
			elif await checkCommand(settings,"verbose",message):
				txtin = message.content[len(prefix+settings["commands"]["verbose"]["command"]):]
				txtout = ""
				synonyms = []
				for word in txtin.split():
					for syn in wordnet.synsets(word):
						for l in syn.lemmas():
							synonyms.append(l.name())
					if not synonyms:
							txtout+=(" " + word)
					else:
						txtout+=(" " + max(set(synonyms), key=len))
					synonyms = []
				txtout = txtout.replace("-"," ")
				txtout = txtout.replace("_"," ")
				print(txtout)
				await client.send_message(message.channel,txtout)

			#SUCCINCT MESSAGE GENERATOR#
			elif await checkCommand(settings,"succinct",message):
				txtin = message.content[len(prefix+settings["commands"]["succinct"]["command"]):]
				txtout = ""
				synonyms = []
				for word in txtin.split():
					for syn in wordnet.synsets(word):
						for l in syn.lemmas():
							synonyms.append(l.name())
					if not synonyms:
						txtout+=(" " + word)
					else:
						txtout+=(" " + min(set(synonyms), key=len))
					synonyms = []
				txtout = txtout.replace("-"," ")
				txtout = txtout.replace("_"," ")
				print(txtout)
				await client.send_message(message.channel,txtout)

			#SMUSH TWO WORDS TOGETHER#
			elif await checkCommand(settings,"smush",message):
				worda = message.content.split(" ")[1]
				wordb = message.content.split(" ")[2]
				asyl = hyphenate_word(worda)
				bsyl = hyphenate_word(wordb)
				if len(bsyl) > 1:
					txtout = str(asyl[0]) + "".join(bsyl[1:])
				else: #in case word 2 is only 1 syllable, just join the words
					txtout = str(asyl[0]) + "".join(bsyl[0])
				txtout = worda+" "+wordb+" ("+txtout+")"
				print(txtout)
				await client.send_message(message.channel,txtout)

			elif await checkCommand(settings,"dog",message):
				with urllib.request.urlopen("https://dog.ceo/api/breeds/image/random") as url:
					data = json.loads(url.read().decode())
					embed = discord.Embed(color=0xeee657)
					embed.set_image(url=data["message"])
					print(data["message"])
					await client.send_message(message.channel,embed=embed)

			elif await checkCommand(settings,"catfact",message):
				with urllib.request.urlopen("https://cat-fact.herokuapp.com/facts/random") as url:
					data = json.loads(url.read().decode())
					txtout=data["text"]
					print(txtout)
					await client.send_message(message.channel,txtout)

			#CHOOSE FROM USER SPECIFIED LIST#
			elif await checkCommand(settings,"choose",message):
				items=message.content[len(prefix+settings["commands"]["choose"]["command"]):]
				txtout=random.choice(items.split("|"))
				print(txtout)
				await client.send_message(message.channel,txtout)

			#"RATE" SOMETHING BY PICKING A NUMBER FROM 1 TO 10#
			elif await checkCommand(settings,"rate",message):
				txtout="I\'d rate " + str(message.content[len(prefix+settings["commands"]["rate"]["command"]):]) + " **" + str(random.randrange(10)) + " out of 10!**"
				print(txtout)
				await client.send_message(message.channel,txtout)

			#FLIP A COIN#
			elif await checkCommand(settings,"flip",message):
				embed = discord.Embed(title="Flip", description=random.choice(['Heads','Tails']), color=0xeee657)
				await client.send_message(message.channel, embed=embed)

			#PRINT EMOTES#
			elif await checkCommand(settings,"emotes",message):
				txtout=""
				with open('emotes.txt','r') as file:
					lines=list(file)
				for x in range(int(message.content.lower().split(" ")[1])):
					txtout += str(random.choice(lines)).rstrip()
				print(message.content.lower().split(" ")[1]+" emojis")

				await client.send_message(message.channel,txtout)

			#PERFORM XKCD37#
			elif settings["commands"]["xkcd37"]["enabled"]==True and re.search(xkcd37,message.content):
				txtout = re.sub(xkcd37,xkcd37sub, message.content, 0)
				txtout = "```> "+txtout+"``` xkcd 37"
				print(txtout)
				await client.send_message(message.channel,txtout)

			#DADBOT#
			elif settings["commands"]["dadbot"]["enabled"]==True and (message.content.lower().split(" ")[0]=='i\'m' or message.content.lower().split(" ")[0]=='im'):
				txtout = "Hi " + " ".join(message.content.split(" ")[1:]) + ", I'm Dad"
				print(txtout)
				await client.send_message(message.channel,txtout)

			#REPLY TO COMMENTS ABOUT BOT#
			elif 'bot' in message.content.lower().split(" ") and settings["commands"]["bot"]["enabled"]==True:
				txtin = sid.polarity_scores(message.content)
				if float(txtin['compound']) >= 0.2:
					txtout=':heart:'
				elif float(txtin['compound']) <= 0.15 and float(txtin['compound']) >= -0.15:
					txtout='I am unfeeling'
				else:
					txtout='no u'
				print(txtout+' '+str(txtin['compound']))
				await client.send_message(message.channel,txtout)

			elif 'oopsie' in message.content.lower().split(" ") and settings["commands"]["oopsie"]["enabled"]==True:
				txtout="OOPSIE WOOPSIE!! Uwu We make a fucky wucky!! A wittle fucko boingo! The code monkeys at our headquarters are working VEWY HAWD to fix this!"
				print(txtout)
				await client.send_message(message.channel,txtout)

			#GARBAGE MEME#
			elif settings["commands"]["peestream"]["command"] in message.content.lower() and settings["commands"]["peestream"]["enabled"]==True:
				embed = discord.Embed(color=0xeee657)
				embed.set_image(url="https://cdn.discordapp.com/attachments/260061122193784833/404628539728723969/chrome_2018-01-07_20-25-17.jpg")
				print("Pee Stream")
				await client.send_message(message.channel,embed=embed)
			txtout = ""

#Check if command should run
async def checkCommand(settings,commandName,message,atStart=True):
	prefix = str(settings["bot"]["prefix"])
	if atStart:
		if message.content.lower().startswith(prefix+settings["commands"][commandName]["command"]) and settings["commands"][commandName]["enabled"]==True:
			return True
		else:
			return False
	else:
		if settings["commands"][commandName]["command"] in message.content.lower() and settings["commands"][commandName]["enabled"]==True:
			return True
		else:
			return False

#Gather messages for quote
async def getQuote(inmessage):
	if inmessage.mentions:
		async for message in client.logs_from(inmessage.channel,before=inmessage.timestamp,reverse=False):
			if message.author == inmessage.mentions[0]:
				return message
	elif len(inmessage.content.split(" "))>1:
		return await getFuzz(inmessage)
	else:
		async for message in client.logs_from(inmessage.channel,before=inmessage.timestamp,reverse=False,limit=2):
			return message

async def fuzz(stringA,stringB):
	return float(difflib.SequenceMatcher(None, stringA, stringB).ratio())

async def getFuzz(inmessage):
	messages = []
	similarity = []
	content = " ".join(inmessage.content.split(" ")[1:])
	async for message in client.logs_from(inmessage.channel,before=inmessage.timestamp,reverse=False):
		messages.append(message)
		similarity.append(await fuzz(content,message.content))
	if max(similarity) >= .68:
		return messages[similarity.index(max(similarity))]
	else:
		return None

#Check if message is positive, negative or neutral
async def sentiment(inmessage):
	return sid.polarity_scores(inmessage.content)

with open("bottoken_topsecret.txt","r") as bottoken:
	client.run(str(bottoken.read()))
client.close()


class First_Bad_Version(object):
    def firstBadVersion(self, n):
        """
        :type n: int
        :rtype: int
        """
        l = 0
        r = n-1
        while l<=r:
            mid = (l+r)/2
            if isBadVersion(mid)==False:
                l=mid+1
            else:
                r=mid-1
        return l

class Sqrt(object):
    def mySqrt(self, x):
        l, r = 0, x
        while l <= r:
            mid = (l+r)/2
            if mid * mid <= x < (mid+1)*(mid+1):
                return mid
            elif x < mid * mid:
                r = mid
            else:
                l = mid + 1

class Divide_Two_Integers(object):
    def divide(self, dividend, divisor):
        """
        :type dividend: int
        :type divisor: int
        :rtype: int
        """
        positive = (dividend < 0) is (divisor < 0)
        dividend, divisor = abs(dividend), abs(divisor)
        res = 0
        while dividend >= divisor:
            temp, i = divisor, 1
            while dividend >= temp:
                dividend -= temp
                res += i
                i <<= 1
                temp <<= 1
        if not positive:
            res = -res

        return min(max(-2147483648, res), 2147483647)

class Search_For_A_Range(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        len_ = len(nums)
        l = 0
        r = len_-1
        mid = (l+r)/2
        flag = -1
        while l<=r and flag<0:
            if nums[mid]>target:
                r = mid-1
                mid = (l+r)/2
            elif nums[mid]<target:
                l = mid+1
                mid = (l+r)/2
            else:
                flag = mid
        if flag<0:
            return [-1,-1]

        l,r = flag,flag

        while l>0 and nums[l-1]==target:
            l-=1

        while r<len_-1 and nums[r+1]==target:
            r+=1

        return [l,r]

class Search_in_Rotated_Sorted_Array_2(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: bool
        """
        nums = sorted(set(nums))

        l,r = 0,len(nums)-1
        while l<=r:
            mid = (l+r)/2
            if nums[mid]<target:
                l = mid+1
            elif nums[mid]>target:
                r = mid-1
            else:
                return True
        return False

class Longest_Increasing_Subsequence(object):

    def lengthOfLIS(self, nums):
        minend = [float('inf')] * (len(nums) + 1)
        for num in nums:
            minend[bisect.bisect_left(minend, num)] = num
        return minend.index(float('inf'))

class Search_a_2D_Matrix(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        col = len(matrix[0])
        end = [rows[col-1] for rows in matrix]

        ind = bisect.bisect_left(end,target)
        if ind==len(matrix):
            return False

        if target in matrix[ind]:
            return True

        return False

class Search_a_2D_Matrix_2(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        col_max = len(matrix[0])
        row = len(matrix)-1
        col = 0

        while col<col_max and row>=0:
            tmp = matrix[row][col]
            if tmp==target:
                return True
            elif tmp<target:
                col+=1
            else:
                row-=1
        return False

class Pow(object):
    def myPow(self, x, n):
        """
        :type x: float
        :type n: int
        :rtype: float
        """
        if n<0:
            return 1/self.myPow(x,-n)
        if n==0:
            return 1
        if n==1:
            return x

        if n==2:
            return x*x

        if n>2:
            if n%2==0:
                tmp = self.myPow(x,n/2)
                return tmp*tmp
            else:
                tmp = self.myPow(x,n/2)
                return tmp*tmp*x

class Minimum_Size_Subarray_Sum(object):
    def minSubArrayLen(self, s, nums):
        """
        :type s: int
        :type nums: List[int]
        :rtype: int
        """
        left = 0
        sum = 0
        result = len(nums)+1

        for right in range(result-1):
            sum+=nums[right]
            while sum>=s:
                result = min(result,right-left+1)
                sum -= nums[left]
                left+=1

        return result if result <= len(nums) else 0

class Search_InsertPosition(object):
    def searchInsert(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left,right = 0,len(nums)-1

        while True:
            if left>=right:
                if target>nums[left]:
                    return left+1
                else:
                    return left
            mid = (left+right)/2
            if nums[mid]==target:
                return mid
            else:
                if nums[mid]>target:
                    right = mid-1
                else:
                    left = mid+1

class Find_Minimum_in_Rotated_Sorted_Array(object):
    def findMin(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        left = 0
        right = len(nums)-1

        while left<right:
            mid = (left+right)/2

            if nums[mid]>nums[right]:
                left = mid+1
            else:
                right = mid
        return nums[right]

class Kth_Smallest_Element_in_a_BST(object):
    def kthSmallest(self, root, k):
        """
        :type root: TreeNode
        :type k: int
        :rtype: int
        """
        i = 0
        list = []
        node = root
        while node or list:
            while node:
                list.append(node)
                node = node.left
            node = list.pop()
            i += 1
            if i==k:
                return node.val

            node = node.right

class Count_Complete_Tree_Nodes(object):
    def getDepth(self,root):
        if not root:
            return 0
        return 1 + self.getDepth(root.left)
    def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        h1 = self.getDepth(root.left)
        h2 = self.getDepth(root.right)
        if h1==h2:
            return pow(2,h1)+self.countNodes(root.right)
        else:
            return pow(2,h2)+self.countNodes(root.left)

class Find_Peak_Element(object):
    def findPeakElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """

        l,r = 0,len(nums)-1

        if l==r:
            return 0
        if nums[0]>nums[1]:
            return 0
        if nums[-1]>nums[-2]:
            return len(nums)-1

        while r-l>1:
            m = (l+r)/2
            if nums[m]>nums[m+1]:
                r = m
            else:
                l = m+1
        return l if (nums[l]>nums[r]) else r

class Search_in_Rotated_Sorted_Array(object):
    def bin_search(self,nums,target):
        l,r = 0,len(nums)-1
        while l<=r:
            mid = (l+r)/2
            if nums[mid]<target:
                l = mid+1
            elif nums[mid]>target:
                r = mid-1
            else:
                return mid
        return -1

    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        if nums==sorted(nums):
            return self.bin_search(nums,target)

        i = 0
        while i<len(nums)-1 and nums[i]<nums[i+1]:
            i+=1

        if target<=nums[i] and target>=nums[0]:
            return self.bin_search(nums[0:i+1],target)
        elif target>=nums[i+1] and target<=nums[-1]:
            tmp = self.bin_search(nums[i+1::],target)
            if tmp== -1:
                return -1
            else:
                return i+1+tmp
        else:
            return -1


from ftw.dictstorage.interfaces import IDictStorage
from ftw.solr.interfaces import ISolrSearch
from ftw.solr.query import escape
from ftw.tabbedview.interfaces import IGridStateStorageKeyGenerator
from opengever.base import _
from opengever.base.behaviors.utils import set_attachment_content_disposition
from opengever.base.reporter import DATE_NUMBER_FORMAT
from opengever.base.solr import batched_solr_results
from opengever.base.solr import OGSolrDocument
from opengever.base.solr.fields import DateListingField
from plone import api
from plone.app.contentlisting.interfaces import IContentListingObject
from Products.Five.browser import BrowserView
from zExceptions import BadRequest
from zope.component import getUtility
from zope.component import queryMultiAdapter
import json

class BaseReporterView(BrowserView):
    """Base class for XLS Reporting views, which provide the functionality
    to use the users grid settings (visible columns, column order).
    """

    @property
    def _columns(self):
        """Returns a list of dicts of all available excel columns.
        """
        raise NotImplementedError

    def columns(self):
        return self.filter_and_order_by_tabbedview_settings(self._columns)

    def filter_and_order_by_tabbedview_settings(self, excel_columns):
        active_columns = []
        tabbedview_columns = self.get_active_tabbedview_columns()
        if not tabbedview_columns:
            return excel_columns

        for col in tabbedview_columns:
            column = self.excel_column_by_tabbedview_name(excel_columns, col.get('id'))
            if column:
                active_columns.append(column)

        return active_columns

    def excel_column_by_tabbedview_name(self, excel_columns, tv_col_name):
        """Get the Excel column matching the given TabbedView column name.

        For Catalog based Excel exports, the Excel column's sort_index is
        identical to the TabbedView column name.
        """
        excel_columns_by_name = {
            col.get('sort_index', col.get('id')): col
            for col in excel_columns
        }
        return excel_columns_by_name.get(tv_col_name)

    def get_grid_state(self, view_name):
        """Load tabbedview gridstate of the logged in users for the given view.
        """
        tabbedview = self.context.restrictedTraverse(
            "@@tabbedview_view-{}".format(view_name), default=None)
        if not tabbedview:
            return None

        generator = queryMultiAdapter((self.context, tabbedview, self.request),
                                      IGridStateStorageKeyGenerator)
        key = generator.get_key()
        storage = IDictStorage(tabbedview)
        state = storage.get(key)

        if not state:
            return {}

        return json.loads(state)

    def get_active_tabbedview_columns(self):
        """Loads corresponding tabbedview grid-state and returns an orderd
        list of the current visible columns.
        """
        view_name = self.request.form.get('view_name', None)
        grid_state = self.get_grid_state(view_name)
        if grid_state:
            return [col for col in
                    grid_state.get('columns') if not col.get('hidden')]

    def return_excel(self, reporter):
        data = reporter()
        if not data:
            msg = _(u'Could not generate the report.')
            api.portal.show_message(msg, request=self.request, type='error')
            return self.request.RESPONSE.redirect(self.context.absolute_url())

        response = self.request.RESPONSE
        response.setHeader(
            'Content-Type',
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        set_attachment_content_disposition(self.request, self.filename)

        return data

class SolrReporterView(BaseReporterView):

    batch_size = 1000
    field_mapper = None

    def __init__(self, *args, **kwargs):
        super(SolrReporterView, self).__init__(*args, **kwargs)
        self.solr = getUtility(ISolrSearch)
        self.fields = self.field_mapper(self.solr)

    def get_selected_items(self):
        paths = self.request.get('paths')
        listing_name = self.request.get('listing_name')
        if not paths and not listing_name:
            return

        if paths and listing_name:
            raise BadRequest('You can query either by paths or by a listing.')

        fields = [col['id'] for col in self.columns()]

        solr_query = {}
        solr_query['rows'] = self.batch_size
        solr_query['fl'] = self.fields.get_query_fields(fields) + ['path']

        if paths:
            self._extend_selected_items_query_by_paths(solr_query, paths)
        elif listing_name:
            self._extend_selected_items_query_by_listing(solr_query, listing_name)

        for batch in batched_solr_results(**solr_query):
            for doc in batch:
                doc = OGSolrDocument(doc, fields=self.solr.manager.schema.fields)
                yield IContentListingObject(doc)

    def _extend_selected_items_query_by_paths(self, query, paths):
        # Sort results according to paths passed in request. Those should be
        # sorted exactly as the user saw them in the UI (classic and geverui).
        query['sort'] = 'score asc'
        query['query'] = 'path:({})'.format(
            'OR '.join(['{}^{}'.format(escape(path), score_value)
                       for score_value, path in enumerate(paths)])
        )

    def _extend_selected_items_query_by_listing(self, solr_query, listing_name):
        listing = queryMultiAdapter((self.context, self.request), name="GET_application_json_@listing")
        listing.listing_name = listing_name
        query, filters, start, rows, sort, field_list, params = listing.prepare_solr_query(self.request.form)

        solr_query['sort'] = sort
        solr_query['query'] = query
        solr_query['filters'] = filters

    @property
    def is_frontend_request(self):
        return 'columns' in self.request

    def columns(self):
        if self.is_frontend_request:
            return self.filter_and_order_by_request_columns(self._columns)
        else:
            return self.filter_and_order_by_tabbedview_settings(self._columns)

    def filter_and_order_by_request_columns(self, excel_columns):
        requested_columns = self.get_requested_column_names()
        return sorted(
            excel_columns,
            key=lambda col: requested_columns.index(col['id'])
        )

    @property
    def _columns(self):
        requested_cols = self.get_requested_column_names()

        columns = []
        for requested_col in requested_cols:
            # Dynamically create a column definition based on field mapper
            field = self.fields.get(requested_col, only_allowed=True)
            if not field:
                continue

            column = {
                'id': field.field_name,
                'accessor': field.accessor,
                'sort_index': field.sort_index,
                'title': field.get_title(),
            }

            if isinstance(field, DateListingField):
                column['number_format'] = DATE_NUMBER_FORMAT

            # Update it with overrides from explicit column settings
            column_settings = self.get_column_settings(requested_col)
            column.update(column_settings)

            columns.append(column)

        return columns

    def get_requested_column_names(self):
        column_names = self.request.get('columns', self.get_default_column_names())
        return map(self.canonical_name, column_names)

    def get_default_column_names(self):
        return [c['id'] for c in self.column_settings if c.get('is_default')]

    @property
    def column_settings_by_id(self):
        return {c['id']: c for c in self.column_settings}

    @property
    def column_aliases(self):
        return dict(
            zip(
                [c.get('alias', c['id']) for c in self.column_settings],
                [c['id'] for c in self.column_settings]
            )
        )

    def canonical_name(self, column_name):
        return self.column_aliases.get(column_name, column_name)

    def get_column_settings(self, column_name):
        return self.column_settings_by_id.get(column_name, {})

    def excel_column_by_tabbedview_name(self, excel_columns, tv_col_name):
        """Get the Excel column matching the given TabbedView column name.

        For Solr based Excel exports, the corresponding sort_index in Solr
        usually matches the TabbedView column name. Exceptions from this rule
        can be controlled using 'tabbedview_column' in the column settings.
        """
        excel_columns_by_id = {col['id']: col for col in excel_columns}
        tabbedview_columns = {
            c.get('tabbedview_column', c['sort_index']): c['id']
            for c in self._columns
        }
        col_id = tabbedview_columns.get(tv_col_name, tv_col_name)
        return excel_columns_by_id.get(col_id)


# Exercise

# Ask the user for a string and print out whether this string is a palindrome or not.
# (A palindrome is a string that reads the same forwards and backwards.)

string = input("Enter a string. I will find out the PALINDROME.\n")

import random
if string == string[::-1]:  # [::-1] reverse the string.
    print(">>>> It is palindrome.")
else:
    print(">>>> It is not palindrome.")

# List Indexing

r = range(0, 10)
ls = []
for i in r:
    i = random.randint(1, 10)
    ls.append(i)
print(ls)
print(ls[1:5:2])

# Strings are Lists

string = "samrat"
for i in string:
    print("Letter: ", i)


from django.conf.urls import patterns, url
from tools import views

from django.views.generic import TemplateView
urlpatterns = patterns('',
    url(r'^tools/',views.personal_tools, name='tools'),
    url(r'^register_tool/', views.register_tool, name='register_tool'),
    url(r'^view_tool/(?P<tool_id>\d+)/$', views.view_tool, name='view_tool'),
    url(r'^move_tool/', views.move_tool, name='move_tool'),
    url(r'^remove_tool/(?P<tool_id>\d+)/$', views.remove_tool, name='remove_tool'),
    url(r'^edit_tool/(?P<tool_id>\d+)/$', views.edit_tool, name='edit_tool'),
    url(r'^request_tool/(?P<tool_id>\d+)/$', views.request_tool, name='request_tool'),
    url(r'^thanks_for_requesting/(?P<request_id>\d+)/$', views.thanks_for_requesting, name='thanks_for_requesting'),
    url(r'^request_accept/(?P<request_id>\d+)/$',views.request_accept, name='request_accept'),
    url(r'^request_decline/(?P<request_id>\d+)/$',views.request_decline, name='request_decline'),
    url(r'^return_tool/(?P<tool_id>\d+)/$', views.return_tool, name='return_tool'),
    url(r'^request_index/',views.request_index, name='request_index'),
    url(r'^community_tools/', views.community_tools, name='community_tools'),
    url(r'^borrowed/', views.borrowed, name='borrowed'),
)


from JumpScale import j
# import JumpScale.grid
# import zmq
import gevent
import gevent.monkey
# monkey.patch_thread()
gevent.monkey.patch_time()
import zmq.green as zmq
import time
from gevent import queue as queue
import JumpScale.baselib.serializers
import JumpScale.grid.serverbase
import inspect

GeventLoop = j.core.gevent.getGeventLoopClass()

class ZDaemon(GeventLoop):

    def __init__(self, port=None, name="", nrCmdGreenlets=50, sslorg="", ssluser="", sslkeyvaluestor=None):
        gevent.monkey.patch_socket()
        GeventLoop.__init__(self)

        self.name = name

        if sslkeyvaluestor == None:
            from JumpScale.baselib.ssl.SSL import SSL
            sslkeyvaluestor = SSL().getSSLHandler(sslkeyvaluestor)

        self.daemon = j.servers.base.getDaemon(name="unknown", sslorg="", ssluser="", sslkeyvaluestor=None)

        # self.ports = [] #is for datachannel
        # self.sockets = {} #is for datachannel
        # self.watchdog = {}  # active ports are in this list

        self.port = port

        if port==None:
            raise RuntimeError("Port cannot be none")

        self.nrCmdGreenlets = nrCmdGreenlets

        self.key = ""

    def addCMDsInterface(self, cmdInterfaceClass, category=""):
        self.daemon.addCMDsInterface(cmdInterfaceClass, category)

    def repCmdServer(self):
        cmdsocket = self.cmdcontext.socket(zmq.REP)
        cmdsocket.connect("inproc://cmdworkers")
        while True:
            category, cmd, informat, returnformat, data, sessionid = cmdsocket.recv_multipart()
            # print "startrpc"
            result = self.daemon.processRPCUnSerialized(cmd, informat, returnformat, data, sessionid, category)
            # print "stoprpc"
            cmdsocket.send_multipart(result)
            # print 'senddonerpc'

    def cmdGreenlet(self):
        # Nonblocking, e.g the osis server contains a broker which queus internally the messages.
        self.cmdcontext = zmq.Context()

        frontend = self.cmdcontext.socket(zmq.ROUTER)
        backend = self.cmdcontext.socket(zmq.DEALER)

        frontend.bind("tcp://*:%s" % self.port)
        backend.bind("inproc://cmdworkers")

        # Initialize poll set
        poller = zmq.Poller()
        poller.register(frontend, zmq.POLLIN)
        poller.register(backend, zmq.POLLIN)

        workers = []

        for i in range(self.nrCmdGreenlets):
            workers.append(gevent.spawn(self.repCmdServer))

        j.logger.log("init cmd channel on port:%s for daemon:%s" % (self.port, self.name), level=5, category="zdaemon.init")

        while True:
            socks = dict(poller.poll())
            if socks.get(frontend) == zmq.POLLIN:
                parts = frontend.recv_multipart()
                parts.append(parts[0])  # add session id at end
                backend.send_multipart([parts[0]] + parts)

            if socks.get(backend) == zmq.POLLIN:
                parts = backend.recv_multipart()
                frontend.send_multipart(parts[1:])  # @todo dont understand why I need to remove first part of parts?

    def start(self, mainloop=None):
        print(("starting %s"%self.name))
        self.schedule("cmdGreenlet", self.cmdGreenlet)
        self.startClock()

        print(("start %s on port:%s"%(self.name,self.port)))
        if mainloop != None:
            mainloop()
        else:
            while True:
                gevent.sleep(100)

    # UNFINISHED CODE FOR DATACHANNEL (still duplicate code inside) ################################

    # def datachannelStart(self):
    #     self.schedule("returok", self.datachannelReturnok)
    #     self.schedule("watchdog",self.watchdogCheck)
    #     self.schedule("watchdogReset",self.watchdogReset)

    # def datachannelProcessor(self, port):
    #     context = zmq.Context()
    #     socket = context.socket(zmq.PAIR)

    #     socket.bind("tcp://*:%s" % port)
    #     self.sockets[port] = socket

    #     self.ports.append(port)

    #     print "init data port:%s"%port
    #     while True:
    #         msg = socket.recv()
    #         self.watchdog[port] = True
    #         if msg == "WATCHDOG":
    #             continue
    #         self.processRPC(msg)

    # def datachannelReturnok(self):
    #     """
    #     will every 5 sec go back to sender to acknowledge succesfull processed items
    #     """
    #     while True:
    #         self.socket.send(str(self.counter))
    # print "send"
    #         gevent.sleep(5)

    # def getfreeportAndSchedule(self, name, method, **args):
    #     """
    #     find a free port & attach method to it

    #     """
    #     found = None
    #     for i in range(5010, 5300):
    #         if i not in self.ports:
    #             found = i
    #             break
    #     if found == None:
    #         raise RuntimeError("Could not find free port")

    #     self.schedule("port_%s"%found, method, port=found, **args)

    #     for i in range(1000):
    #         if found in self.ports:
    #             return found
    #         gevent.sleep(0.01)

    #     j.errorconditionhandler.raiseOperationalCritical(msgpub="Cannot open port nr %s for client daemon."%found,
    #                                                      message="", category="grid.startup", die=False, tags="")
    #     return 0

    # def watchdogCheck(self):
    # ports without activity are closed
    #     while True:
    #         gevent.sleep(100)
    #         for port in self.ports:
    #             if port not in self.watchdog:
    #                 self.resetPort(port)

    # def resetPort(self, port):
    #     greenlet = self.greenlets["port_%s"%port]
    #     greenlet.kill()
    #     self.sockets[port].setsockopt(zmq.LINGER, 0)
    #     self.sockets[port].close()
    #     print "Killed socket %s"%port
    #     try:
    #         self.watchdog.pop(port)
    #     except:
    #         pass
    #     try:
    #         self.ports.remove(port)
    #     except:
    #         pass

    # def watchdogReset(self):
    #     while True:
    #         gevent.sleep(10)
    # self.watchdog = {}  # reset watchdog table

    #


#!/usr/bin/env /data/mta/Script/Python3.6/envs/ska3/bin/python

#####################################################################################
#                                                                                #
#           create_otg_time_list.py: create otg time start stop time list files     #
#                                                                                #
#           author: t. isobe (tisobe@cfa.harvard.edu)                               #
#                                                                                #
#           last update: May 28, 2019                                               #
#                                                                                #
#####################################################################################

import sys
import os
import string
import re
import getpass
import fnmatch
import numpy
import getopt
import os.path
import time
import astropy.io.fits  as pyfits
import Chandra.Time
import random
path = '/data/mta/Script/MTA_limit_trends/Scripts/house_keeping/dir_list'

with open(path, 'r') as f:
    data = [line.strip() for line in f.readlines()]

for ent in data:
    atemp = re.split(':', ent)
    var  = atemp[1].strip()
    line = atemp[0].strip()
    exec("%s = %s" %(var, line))

sys.path.append(mta_dir)
sys.path.append(bin_dir)

import mta_common_functions     as mcf  #---- mta common functions
import envelope_common_function as ecf  #---- collection of functions used in envelope fitting
#
#--- set a temporary file name
#
rtail  = int(time.time() * random.random())
zspace = '/tmp/zspace' + str(rtail)
#
#--- other settings
#
na     = 'na'

otg = '/data/mta_www/mta_otg/OTG_filtered.rdb'

cname_list = ['retr_hetg', 'retr_letg', 'insr_hetg', 'insr_letg', 'grat_active', 'grat_inactive']

#------------------------------------------------------------------------------------
#-- create_otg_time_list: create otg time start stop time list files              ---
#------------------------------------------------------------------------------------

def create_otg_time_list():
    """
    create otg time start stop time list files
    input:  none
    output: in <house_keeping>, 'retr_hetg', 'retr_letg', 'insr_hetg', 'insr_letg', 'inactive'
    """
    otg_data = otg_separate()

    for k in range(0, 6):
        line = ''
        [start, stop] =  otg_data[k]
        for m in range(0, len(start)):
            line = line + str(start[m]) + '\t' + str(stop[m]) + '\n'

        ofile = house_keeping + cname_list[k]
        with open(ofile, 'w') as fo:
            fo.write(line)

#------------------------------------------------------------------------------------
#-- otg_separate: create lists of lists of starting and stopping times of each category
#------------------------------------------------------------------------------------

def otg_separate():
    """
    create lists of lists of starting and stopping times of each category
    input:  none, but read from /data/mta_www/mta_otg/OTG_filtered.rdb
    output: a list of lists of [[starting time]. [stopping time]] of each category
            see cname_list for the order of the category
    """
    data = mcf.read_data_file(otg)

    retr_hetg_b = []
    retr_hetg_e = []

    retr_letg_b = []
    retr_letg_e = []

    insr_hetg_b = []
    insr_hetg_e = []

    insr_letg_b = []
    insr_letg_e = []

    active_b    = []
    active_e    = []

    inactive_b  = []
    inactive_e  = []

    for ent in data:
        atemp = re.split('\s+', ent)

        direction = atemp[0].lower()        #--- reter or insr
        grating   = atemp[1].lower()        #--- hetg or letg
#
#--- starting and stopping time of the condition
#
        try:
            start     = float(atemp[2])
        except:
            continue

        start     = time_conversion(start)
        stop      = float(atemp[4])
        stop      = time_conversion(stop)

        if direction == 'insr':
            if grating == 'hetg':
                insr_hetg_b.append(start)
                insr_hetg_e.append(stop)

            elif grating == 'letg':
                insr_letg_b.append(start)
                insr_letg_e.append(stop)

            active_b.append(start)
            active_e.append(stop)

            if (len(inactive_b) > 0) and (start > inactive_b[-1]):
                inactive_e.append(start)

        elif direction == 'retr':
            if grating == 'hetg':
                retr_hetg_b.append(start)
                retr_hetg_e.append(stop)

            elif grating == 'letg':
                retr_letg_b.append(start)
                retr_letg_e.append(stop)

            active_b.append(start)
            active_e.append(stop)

            if len(inactive_b) == len(inactive_e):
                inactive_b.append(stop)

            elif len(inactive_b) > len(inactive_e):
                inactive_b = inactive_b[:-1]

            elif len(inactive_b) < len(inactive_e):
                inactive_e = inactive_e[:-1]
                inactive_b.append(stop)
#
#--- the end of the inactive category is usually open; so close it with today's date
#
    stday = time.strftime("%Y:%j:%H:%M:%S", time.gmtime())
    stop  = Chandra.Time.DateTime(stday).secs
    inactive_e.append(stop)

    return [[retr_hetg_b, retr_hetg_e], [retr_letg_b, retr_letg_e], [insr_hetg_b, insr_hetg_e],\
            [insr_letg_b, insr_letg_e], [active_b, active_e], [inactive_b, inactive_e]]

#------------------------------------------------------------------------------------
#-- time_conversion: convert time format from <yyyyddd.ddd> to second from 1998.1.1--
#------------------------------------------------------------------------------------

def time_conversion(atime):
    """
    convert time format from <yyyyddd.ddd> to second from 1998.1.1
    input:  time    --- time in <yyyyddd.ddd> format
    output: time    --- time in second from 1998.1.1
    """
    atime = str(atime)

    year = str(atime[0:4])
    yday = str(atime[4:7])

    fday = float('0' + atime[7:])

    val  = 24 * fday
    hh   = int(val)
    val  = 60 * (val - hh)
    mm   = int(val)
    ss   = 60 * (val - mm)
    ss   = int(ss)

    lhh  = mcf.add_leading_zero(hh)
    lmm  = mcf.add_leading_zero(mm)
    lss  = mcf.add_leading_zero(ss)

    time = year + ':' + yday + ':' + lhh + ':' + lmm + ':' + lss

    time = Chandra.Time.DateTime(time).secs

    return time

#-------------------------------------------------------------------------------------------
#-- find_the_last_entry_time: find the last logged time                                   --
#-------------------------------------------------------------------------------------------

def find_the_last_entry_time(fits):
    """
    find the last logged time
    input:  fits    --- fits file name
    output: ctime   --- the last logged time
    """
    f = pyfits.open(fits)
    data = f[1].data
    f.close()

    ctime = numpy.max(data['time'])

    return ctime

#------------------------------------------------------------------------------------

if __name__ == "__main__":

    if len(sys.argv) > 1:
        ltype = sys.argv[1]
    else:
        ltype = ''

    create_otg_time_list()


import folium
import pandas

data = pandas.read_csv('Volcanoes_USA.txt')
lon = list(data['LON'])
lat = list(data['LAT'])
elev = list(data['ELEV'])
#name = list(data['NAME'])

def color_producer(elevation):
    if elevation <= 2000:
        return 'green'
    elif elevation > 2000 and elevation <= 3500:
        return 'orange'
    else:
        return 'red'

map = folium.Map(location=[38.58, -99.09], zoom_start=6, tiles="Mapbox Bright")

fgv = folium.FeatureGroup(name='Volcanoes')

for lati, long, ele in zip(lat,lon,elev):
    fgv.add_child(folium.CircleMarker(location=[lati, long], radius=5, popup=str(ele) + " moh", fill_color=color_producer(ele), color='grey', fill=True, fill_opacity=0.8))
    # fg.add_child(folium.Marker -> for andre ikoner på kartet)

fgp = folium.FeatureGroup(name='Population')

fgp.add_child(folium.GeoJson(data=open('world.json', 'r', encoding='utf-8-sig').read(),
                            style_function=lambda x: {'fillColor':'green' if x['properties']['POP2005'] < 10000000
                                                      else 'orange' if 10000000 <= x['properties']['POP2005'] < 20000000
                                                      else 'red'}))

map.add_child(fgv)
map.add_child(fgp)
map.add_child(folium.LayerControl())

map.save('Map1.html')


import re, itertools
from collections import defaultdict
from functools import partial

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db import models
from django.contrib.auth.models import User
import boto3
from boto3 import client
from django.conf import settings

ORGANIZATION = (
  ('', '--Select Organization--'),
  ('KH', 'Cambodia'),
  ('EC', 'Ecuador'),
  ('HN', 'Honduras'),
  ('KE', 'Kenya'),
  ('MM', 'Myanmar'),
  ('PH', 'Philippines'),
  ('LK', 'Sri Lanka'),
  ('TZ', 'Tanzania'),
  ('UG', 'Uganda'),
  ('ZM', 'Zambia'),
  ('VFI', 'VisionFund International'),
  ('AFR', 'Africa Regional'),
  ('ASR', 'Asia Regional'),
  ('LAR', 'Latin America Regional'),
)

class Map(models.Model):
#    class Meta:
#        permissions = (
#          ("KE", "Kenya Permission"),
#        )

    linkto_map = models.TextField()

    def __str__(self):
      return self.linkto_map

class Profile(models.Model):
    user = models.OneToOneField(User, related_name='profile')
    organization = models.CharField(max_length=3, choices=ORGANIZATION, default='None')

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

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
      Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

class s3resource():
    def __init__(self):
        self.conn = boto3.client(
            's3',
            aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
            aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
        )
        self.all_list = []

    def return_maps(self, country):
        mapmatrix = self.conn.list_objects(Bucket='wmicopy', Prefix= 'maps/' + country + '/')['Contents']
        path_id = []
        for file in mapmatrix:
            key_string = file['Key']
            if not key_string.endswith('/'):
                path_id.append(key_string)

        url_list = []
        for file in mapmatrix:
            key_string = file['Key']
            if not key_string.endswith('/'):
                url_string = 'https://s3-us-west-2.amazonaws.com/wmicopy/' + key_string
                url_list.append( url_string)

        country_list = []
        for file in mapmatrix:
            key_string = file['Key']
            if not key_string.endswith('/'):
                country_list.append(re.findall(r'(\w+)', key_string)[1])

        theme_list = []
        for file in mapmatrix:
            key_string = file['Key']
            if not key_string.endswith('/'):
                theme_list.append(re.findall(r'(\w+)', key_string)[2])

        name_list = []
        for file in mapmatrix:
            key_string = file['Key']
            if not key_string.endswith('/'):
#                match = re.search(r'([A-Z])\w+([-\s+])?\w+', key_string) **Old regex**
                match = re.search(r'[A-Z][\w\s:-]+', key_string)
                if match:
                    name_list.append(match.group(0))

        all_list = [] #combine all the lists
        all_list.append(path_id)
        all_list.append(country_list)
        all_list.append(theme_list)
        all_list.append(url_list)
        all_list.append(name_list)

        link_list = []
        for i in range(len(all_list[0])):
            url_dict = {all_list[3][i]:all_list[4][i]}
            theme_dict = {all_list[2][i]:url_dict}
            link_list.append({all_list[1][i]:theme_dict})
        return(link_list)

    def country_filter(self, country):
        output = []
        link_list = self.return_maps(country)
        for i in link_list:
          for key, value in i.items():
            if key == country:
              output.append(value)
        return output


import re
import subprocess
from mock import patch

import pytest

import manage
from webservices import rest
from webservices.load_current_murs import parse_regulatory_citations, parse_statutory_citations
from tests.common import TEST_CONN, BaseTestCase

@pytest.mark.parametrize("test_input,case_id,entity_id,expected", [
    ("110", 1, 2,
        [{"text": "11 C.F.R. 110", "url": "/regulations/110/CURRENT"}]),
    ("110.21", 1, 2,
        [{"text": "11 C.F.R. 110.21", "url": "/regulations/110-21/CURRENT"}]),
])
def test_parse_regulatory_citations(test_input, case_id, entity_id, expected):
    assert parse_regulatory_citations(test_input, case_id, entity_id) == expected

def test_parse_statutory_citations_with_reclassifications():
    assert parse_statutory_citations("431", 1, 2) == [{
        "text": "52 U.S.C. 30101",
        "url": "https://api.fdsys.gov/link?collection=uscode&year=mostrecent&link-type=html&title=52&section=30101"}]

def test_parse_statutory_citations_no_reclassifications():
    assert parse_statutory_citations("30101", 1, 2) == [{
        "text": "52 U.S.C. 30101",
        "url": "https://api.fdsys.gov/link?collection=uscode&year=mostrecent&link-type=html&title=52&section=30101"}]

def assert_es_index_call(call_args, expected_mur):
    index, doc_type, mur = call_args[0]
    assert index == 'docs'
    assert doc_type == 'murs'
    assert mur == expected_mur

class TestLoadCurrentMURs(BaseTestCase):
    @classmethod
    def setUpClass(cls):
        super(TestLoadCurrentMURs, cls).setUpClass()
        subprocess.check_call(
            ['psql', TEST_CONN, '-f', 'data/load_murs_schema.sql'])

    @classmethod
    def tearDownClass(cls):
        subprocess.check_call(
            ['psql', TEST_CONN, '-c', 'DROP SCHEMA fecmur CASCADE'])
        super(TestLoadCurrentMURs, cls).tearDownClass()

    def setUp(self):
        self.connection = rest.db.engine.connect()

    def tearDown(self):
        self.clear_test_data()
        self.connection.close()
        rest.db.session.remove()

    @patch('webservices.load_current_murs.get_bucket')
    @patch('webservices.load_current_murs.get_elasticsearch_connection')
    def test_simple_mur(self, get_es_conn, get_bucket):
        mur_subject = 'Fraudulent misrepresentation'
        expected_mur = {
            'no': '1',
            'name': 'Simple MUR',
            'mur_type': 'current',
            'text': '',
            'doc_id': 'mur_1',
            'participants': [],
            'subject': {"text": [mur_subject]},
            'documents': []
        }
        self.create_mur(1, expected_mur['no'], expected_mur['name'], mur_subject)
        manage.load_current_murs()
        index, doc_type, mur = get_es_conn.return_value.index.call_args[0]

        assert index == 'docs'
        assert doc_type == 'murs'
        assert mur == expected_mur

    @patch('webservices.env.env.get_credential', return_value='BUCKET_NAME')
    @patch('webservices.load_current_murs.get_bucket')
    @patch('webservices.load_current_murs.get_elasticsearch_connection')
    def test_mur_with_participants_and_documents(self, get_es_conn, get_bucket, get_credential):
        case_id = 1
        mur_subject = 'Fraudulent misrepresentation'
        expected_mur = {
            'no': '1',
            'name': 'MUR with participants',
            'mur_type': 'current',
            'doc_id': 'mur_1',
            'subject': {"text": [mur_subject]},
        }
        participants = [
            ("Complainant", "Gollum"),
            ("Respondent", "Bilbo Baggins"),
            ("Respondent", "Thorin Oakenshield")
        ]
        documents = [
            ('A Category', 'Some text'),
            ('Another Category', 'Different text'),
        ]

        self.create_mur(case_id, expected_mur['no'], expected_mur['name'], mur_subject)
        for entity_id, participant in enumerate(participants):
            role, name = participant
            self.create_participant(case_id, entity_id, role, name)
        for document_id, document in enumerate(documents):
            category, ocrtext = document
            self.create_document(case_id, document_id, category, ocrtext)

        manage.load_current_murs()
        index, doc_type, mur = get_es_conn.return_value.index.call_args[0]

        assert index == 'docs'
        assert doc_type == 'murs'
        for key in expected_mur:
            assert mur[key] == expected_mur[key]

        assert participants == [(p['role'], p['name'])
                                for p in mur['participants']]

        assert mur['text'].strip() == "Some text Different text"

        assert [(d[0], len(d[1])) for d in documents] == [
            (d['category'], d['length']) for d in mur['documents']]
        for d in mur['documents']:
            assert re.match(r'https://BUCKET_NAME.s3.amazonaws.com/legal/murs/current', d['url'])

    @patch('webservices.env.env.get_credential', return_value='BUCKET_NAME')
    @patch('webservices.load_current_murs.get_bucket')
    @patch('webservices.load_current_murs.get_elasticsearch_connection')
    def test_mur_with_citations(self, get_es_conn, get_bucket, get_credential):
        case_id = 1
        mur_subject = 'Fraudulent misrepresentation'
        expected_mur = {
            'no': '1',
            'name': 'MUR with participants',
            'mur_type': 'current',
            'doc_id': 'mur_1',
            'subject': {"text": [mur_subject]},
        }
        participants = [
            ("Complainant", "Gollum"),
            ("Respondent", "Bilbo Baggins", "RTB", "345", ""),
            ("Respondent", "Thorin Oakenshield", "Closed", "123", "456")
        ]

        self.create_mur(case_id, expected_mur['no'], expected_mur['name'], mur_subject)
        for entity_id, participant in enumerate(participants):
            if len(participant) == 5:
                role, name, stage, statutory_citation, regulatory_citation = participant
                self.create_participant(case_id, entity_id, role, name, stage, statutory_citation, regulatory_citation)
            else:
                role, name = participant
                self.create_participant(case_id, entity_id, role, name)

        manage.load_current_murs()
        index, doc_type, mur = get_es_conn.return_value.index.call_args[0]

        assert index == 'docs'
        assert doc_type == 'murs'
        for key in expected_mur:
            assert mur[key] == expected_mur[key]

        gollum = [p for p in mur['participants']
                  if p['name'] == 'Gollum'][0]
        assert gollum['role'] == 'Complainant'

        bilbo = [p for p in mur['participants']
                 if p['name'] == 'Bilbo Baggins'][0]
        assert bilbo['role'] == 'Respondent'
        assert len(bilbo['citations']['RTB']) == 1
        assert bilbo['citations']['RTB'] == [{
            'text': '52 U.S.C. 345',
            'url': 'https://api.fdsys.gov/link?collection=uscode&year=mostrecent&link-type=html&title=52&section=345'
        }]

        thorin = [p for p in mur['participants']
                 if p['name'] == 'Thorin Oakenshield'][0]
        assert thorin['role'] == 'Respondent'
        assert len(thorin['citations']['Closed']) == 2
        assert thorin['citations']['Closed'] == [{
            'text': '52 U.S.C. 123',
            'url': 'https://api.fdsys.gov/link?collection=uscode&year=mostrecent&link-type=html&title=52&section=123'
        }, {
            'text': '11 C.F.R. 456',
            'url': '/regulations/456/CURRENT'
        }]

    def create_mur(self, case_id, case_no, name, subject_description):
        subject_id = self.connection.execute(
            "SELECT subject_id FROM fecmur.subject "
            " WHERE description = %s ", subject_description).scalar()
        self.connection.execute(
            "INSERT INTO fecmur.case (case_id, case_no, name, case_type) "
            "VALUES (%s, %s, %s, 'MUR')", case_id, case_no, name)
        self.connection.execute(
            "INSERT INTO fecmur.case_subject (case_id, subject_id, relatedsubject_id) "
            "VALUES (%s, %s, -1)", case_id, subject_id)

    def create_participant(self, case_id, entity_id, role, name,
            stage=None, statutory_citation=None, regulatory_citation=None):
        role_id = self.connection.execute(
            "SELECT role_id FROM fecmur.role "
            " WHERE description = %s ", role).scalar()
        self.connection.execute(
            "INSERT INTO fecmur.entity (entity_id, name) "
            "VALUES (%s, %s)", entity_id, name)
        self.connection.execute(
            "INSERT INTO fecmur.players (player_id, entity_id, case_id, role_id) "
            "VALUES (%s, %s, %s, %s)", entity_id, entity_id, case_id, role_id)
        if stage:
            self.create_citation(case_id, entity_id, stage, statutory_citation, regulatory_citation)

    def create_citation(self, case_id, entity_id, stage, statutory_citation, regulatory_citation):
        self.connection.execute(
            "INSERT INTO fecmur.violations (case_id, entity_id, stage, statutory_citation, regulatory_citation) "
            "VALUES (%s, %s, %s, %s, %s)", case_id, entity_id, stage, statutory_citation, regulatory_citation)

    def create_document(self, case_id, document_id, category, ocrtext):
        self.connection.execute(
            "INSERT INTO fecmur.document (document_id, doc_order_id, case_id, category, ocrtext, fileimage) "
            "VALUES (%s, %s, %s, %s, %s, %s)", document_id, document_id, case_id, category, ocrtext, ocrtext)

    def clear_test_data(self):
        tables = [
            "violations",
            "document",
            "players",
            "entity",
            "case_subject",
            "case",
        ]
        for table in tables:
            self.connection.execute("DELETE FROM fecmur.{}".format(table))


#!/usr/bin/env python

from StrippingUtils import LineBuilderTests

config_params =  {
    'UseNoPIDsHadrons'          : True,
    'Prescale_BdToKstarMuMu'    : 1.0,
    'Postscale_BdToKstarMuMu'   : 1.0,
    'Prescale_BdToKstarMuMuSS'  : 1.0,
    'Postscale_BdToKstarMuMuSS' : 1.0,
    'Prescale_BuToKMuMu'        : 1.0,
    'Postscale_BuToKMuMu'       : 1.0,
    'Prescale_BuToKMuMuSS'      : 1.0,
    'Postscale_BuToKMuMuSS'     : 1.0,
    'B_Comb_MassLow'            : 4600.0,
    'B_Comb_MassHigh'           : 6000.0,
    'B_MassLow'                 : 4850.0,
    'B_MassHigh'                : 5780.0,
    'B_VertexCHI2'              : 6.0,
    'B_IPCHI2'                  : 16.0,
    'B_DIRA'                    : 0.014,
    'B_FlightCHI2'              : 121.0,
    'Dau_VertexCHI2'            : 12.0,
    'Dau_DIRA'                  : -0.9,
    'Kstar_Comb_MassLow'        : 550.0,
    'Kstar_Comb_MassHigh'       : 2200.0,
    'Kstar_MassLow'             : 600.0,
    'Kstar_MassHigh'            : 2000.0,
    'Kstar_MinIPCHI2'           : 4.0,
    'Kstar_FlightChi2'          : 25.0,
    'Dimu_FlightChi2'           : 81.0,
    'Track_CHI2nDOF'            : 5.0,
    'Hadron_MinIPCHI2'          : 9.0,
    'Muon_MinIPCHI2'            : 9.0,
    'Muon_IsMuon'               : False,
    'B_Dau_MaxIPCHI2'           : 9.0,
    'Kstar_Dau_MaxIPCHI2'       : 9.0,
    'Dimu_Dau_MaxIPCHI2'        : 9.0
    }

from StrippingSelections.StrippingBd2KstarMuMu import StrippingBdToKstarMuMuConf as builder

def test_line_builder() :
    LineBuilderTests.test_line_builder(builder, config_params)

if __name__ == '__main__' :

    test_line_builder()


status_list=[]
def add_status(current_status_message):
    print("Display current message")
    if current_status_message == None:
        print("U don't have any current status message yet")
        print("U have to insert a new status")
        new_status_message=input("Enter a new status ")
        if len(new_status_message) > 0:
            updated_status=new_status_message
        status_list.append(updated_status)
        return updated_status

            #sprint(status_list)
    else:
        print("Your current message is :" , current_status_message)
        update_choice=input("If u want to select older status then prnt 'y' or add a status then print 'n' :")

        if update_choice.upper()=='Y':
            for i in range(len(status_list)):
                print(str(i+1)+ " " + status_list[i])
            message_selection = int(input("Enter a number which u want to select"))
            updated_status=status_list[message_selection-1]
            return updated_status

        elif update_choice.upper() == 'N':
            print("U want to add a status")
            new_status_message=input("Enter a status")
            if len(new_status_message) > 0:
                updated_status=new_status_message
            status_list.append(updated_status)
            return updated_status


from datetime import datetime
import logging
import os
import tkinter
from tkinter import filedialog, messagebox

from huginn import connections, tracks
from huginn.connections import Radio
from huginn.logger import HuginnLogger
from huginn.writer import write_aprs_packet_tracks

BALLOON_CALLSIGNS = ['W3EAX-10', 'W3EAX-11', 'W3EAX-14']
INTERVAL_SECONDS = 5
DESKTOP_PATH = os.path.join(os.path.expanduser('~'), 'Desktop')

class HuginnGUI:
    def __init__(self):
        self.main_window = tkinter.Tk()
        self.main_window.title('huginn main')

        self.connections = []

        self.active = False
        self.packet_tracks = {}

        self.frames = {}
        self.elements = {}
        self.last_row = 0

        self.frames['top'] = tkinter.Frame(self.main_window)
        self.frames['top'].pack()

        self.frames['separator'] = tkinter.Frame(height=2, bd=1, relief=tkinter.SUNKEN)
        self.frames['separator'].pack(fill=tkinter.X, padx=5, pady=5)

        self.frames['bottom'] = tkinter.Frame(self.main_window)
        self.frames['bottom'].pack()

        self.__add_entry_box(self.frames['top'], 'port')

        self.__add_entry_box(self.frames['top'], title='log_file', width=45)
        self.elements['log_file'].insert(0, os.path.join(DESKTOP_PATH, f'huginn_log_{datetime.now():%Y%m%dT%H%M%S}.txt'))
        log_file_button = tkinter.Button(self.frames['top'], text='...', command=self.__select_log_file)
        log_file_button.grid(row=self.last_row, column=2)

        self.__add_entry_box(self.frames['top'], title='output_file', width=45)
        self.elements['output_file'].insert(0, os.path.join(DESKTOP_PATH, f'huginn_output_{datetime.now():%Y%m%dT%H%M%S}.geojson'))
        output_file_button = tkinter.Button(self.frames['top'], text='...', command=self.__select_output_file)
        output_file_button.grid(row=self.last_row, column=2)

        self.toggle_text = tkinter.StringVar()
        self.toggle_text.set('Start')
        toggle_button = tkinter.Button(self.frames['top'], textvariable=self.toggle_text, command=self.toggle)
        toggle_button.grid(row=self.last_row + 1, column=1)
        self.last_row += 1

        self.__add_text_box(self.frames['bottom'], title='longitude', units='°')
        self.__add_text_box(self.frames['bottom'], title='latitude', units='°')
        self.__add_text_box(self.frames['bottom'], title='altitude', units='m')
        self.__add_text_box(self.frames['bottom'], title='ground_speed', units='m/s')
        self.__add_text_box(self.frames['bottom'], title='ascent_rate', units='m/s')

        for element in self.frames['bottom'].winfo_children():
            element.configure(state=tkinter.DISABLED)

        try:
            self.serial_port = connections.port()
            self.replace_text(self.elements['port'], self.serial_port)
        except OSError:
            self.serial_port = None

        self.logger = HuginnLogger('huginn')

        self.main_window.mainloop()

    def __add_text_box(self, frame: tkinter.Frame, title: str, units: str = None, row: int = None, entry: bool = False,
                       width: int = 10):
        if row is None:
            row = self.last_row + 1

        column = 0

        element_label = tkinter.Label(frame, text=title)
        element_label.grid(row=row, column=column)

        column += 1

        if entry:
            element = tkinter.Entry(frame, width=width)
        else:
            element = tkinter.Text(frame, width=width, height=1)

        element.grid(row=row, column=column)

        column += 1

        if units is not None:
            units_label = tkinter.Label(frame, text=units)
            units_label.grid(row=row, column=column)

        column += 1

        self.last_row = row

        self.elements[title] = element

    def __add_entry_box(self, frame: tkinter.Frame, title: str, row: int = None, width: int = 10):
        self.__add_text_box(frame, title, row=row, entry=True, width=width)

    def __select_log_file(self):
        filename = os.path.splitext(self.elements['log_file'].get())[0]
        path = filedialog.asksaveasfilename(title='Huginn log location...', initialfile=filename,
                                            defaultextension='.txt', filetypes=[('Text', '*.txt')])

        if path != '':
            self.replace_text(self.elements['log_file'], path)

    def __select_output_file(self):
        filename = os.path.splitext(self.elements['output_file'].get())[0]
        path = filedialog.asksaveasfilename(title='Huginn output location...', initialfile=filename,
                                            defaultextension='.kml', filetypes=[('GeoJSON', '*.geojson'), ('Keyhole Markup Language', '*.kml')])
        if path != '':
            self.replace_text(self.elements['output_file'], path)

    def toggle(self):
        if self.active:
            for connection in self.connections:
                connection.close()

                if type(connection) is Radio:
                    self.logger.info(f'closing port {connection.serial_port}')

            for element in self.frames['bottom'].winfo_children():
                element.configure(state=tkinter.DISABLED)

            self.toggle_text.set('Start')
            self.active = False
            self.connections = []

            self.logger.info('stopping')
            logging.shutdown()
        else:
            log_filename = self.elements['log_file'].get()
            self.logger.filename = log_filename
            self.logger.info('starting')

            try:
                if self.serial_port is None:
                    self.serial_port = self.elements['port'].get()

                    if self.serial_port == '':
                        try:
                            self.serial_port = connections.port()
                            self.replace_text(self.elements['port'], self.serial_port)
                        except Exception as error:
                            self.logger.error(f'{error.__class__.__name__}: {error}')
                            self.serial_port = None

                if self.serial_port is not None:
                    if 'txt' in self.serial_port:
                        try:
                            text_file = connections.TextFile(self.serial_port)
                            self.connections.append(text_file)
                        except Exception as error:
                            self.logger.error(f'{error.__class__.__name__}: {error}')
                    else:
                        try:
                            radio = connections.Radio(self.serial_port)
                            self.serial_port = radio.serial_port
                            self.logger.info(f'opened port {self.serial_port}')
                            self.connections.append(radio)
                        except Exception as error:
                            self.logger.error(f'{error.__class__.__name__}: {error}')

                try:
                    aprs_api = connections.APRS_fi(BALLOON_CALLSIGNS)
                    self.logger.info(f'established connection to API')
                    self.connections.append(aprs_api)
                except Exception as error:
                    self.logger.error(f'{error.__class__.__name__}: {error}')

                if len(self.connections) == 0:
                    raise ConnectionError('Could not establish connection to APRS packet source.')

                for element in self.frames['bottom'].winfo_children():
                    element.configure(state=tkinter.NORMAL)

                self.toggle_text.set('Stop')
                self.active = True
            except Exception as error:
                messagebox.showerror('Huginn Error', f'{error.__class__.__name__}: {error}')
                self.active = False

            self.run()

    def run(self):
        if self.active:
            self.logger.debug(f'receiving packets from {len(self.connections)} source(s)')

            parsed_packets = []
            for connection in self.connections:
                parsed_packets.extend(connection.packets)

            self.logger.debug(f'received {len(parsed_packets)} packets')

            if len(parsed_packets) > 0:
                for parsed_packet in parsed_packets:
                    callsign = parsed_packet['callsign']

                    if callsign in self.packet_tracks:
                        if parsed_packet not in self.packet_tracks[callsign]:
                            self.packet_tracks[callsign].append(parsed_packet)
                        else:
                            self.logger.debug(f'{callsign:8} - received duplicate packet: {parsed_packet}')
                            continue
                    else:
                        self.packet_tracks[callsign] = tracks.APRSTrack(callsign, [parsed_packet])
                        self.logger.debug(f'{callsign:8} - started tracking')

                    self.logger.info(f'{callsign:8} - received new packet: {parsed_packet}')
                    packet_track = self.packet_tracks[callsign]

                    if 'longitude' in parsed_packet and 'latitude' in parsed_packet:
                        coordinates = packet_track.coordinates[-1]
                        ascent_rate = packet_track.ascent_rate[-1]
                        ground_speed = packet_track.ground_speed[-1]
                        seconds_to_impact = packet_track.seconds_to_impact

                        self.logger.info(f'{callsign:8} - Ascent rate (m/s): {ascent_rate}')
                        self.logger.info(f'{callsign:8} - Ground speed (m/s): {ground_speed}')
                        if seconds_to_impact >= 0:
                            self.logger.info(f'{callsign:8} - Estimated time until landing (s): {seconds_to_impact}')

                        if callsign in BALLOON_CALLSIGNS:
                            self.replace_text(self.elements['longitude'], coordinates[0])
                            self.replace_text(self.elements['latitude'], coordinates[1])
                            self.replace_text(self.elements['altitude'], coordinates[2])
                            self.replace_text(self.elements['ground_speed'], ground_speed)
                            self.replace_text(self.elements['ascent_rate'], ascent_rate)

                output_filename = self.elements['output_file'].get()
                if output_filename != '':
                    write_aprs_packet_tracks(self.packet_tracks.values(), output_filename)

            if self.active:
                self.main_window.after(INTERVAL_SECONDS * 1000, self.run)

    @staticmethod
    def replace_text(element, value):
        if type(element) is tkinter.Text:
            start_index = '1.0'
        else:
            start_index = 0

        element.delete(start_index, tkinter.END)
        element.insert(start_index, value)

if __name__ == '__main__':
    huginn_gui = HuginnGUI()


import asyncio

async def tcp_echo_client(message, loop):
    reader, writer = await asyncio.open_connection('210.100.235.128', 3456, loop=loop)

    print('Send: %r' % message)
    for word in message:
        writer.write(word.encode())

    data = await reader.read(1000)
    print('Received: %r' % data.decode())

    print('Close the socket')
    writer.close()

data = "qwer asdf zxcv"
message = data.split(" ")
loop = asyncio.get_event_loop()
loop.run_until_complete(tcp_echo_client(message, loop))
loop.close()


from math import pi

SIMULATION_SPEED = 0.01 # seconds
CULL_PERIOD = 300
VISUALISE = True

ENV_WIDTH = 500
ENV_HEIGHT = 500
ENV_N_FOOD = 20
ENV_N_ANIMALS = 10

MUTATION_RATE = 0.02

CLONE_NUM = 5

FOOD_RADIUS = 5
FOOD_COLOR = "yellow"

ANIMAL_HEAD_RADIUS  = 5
ANIMAL_HEAD_COLOR   = "red"
ANIMAL_BODY_LENGTH  = 15
ANIMAL_BODY_COLOR   = "black"

""" neural network constants """
NUM_INPUTS = 1
NUM_OUTPUTS = 2
NUM_HIDDEN_NEURONS = 30

THRESHOLD_OUTPUT = 0.75

ANIMAL_MOVE_SPEED = 2
ANIMAL_MOVE_ANGLE = pi / 8

NUM_CHILDREN = 1

FOOD_STRENGTH = 1
FOOD_EAT_DISTANCE = FOOD_RADIUS


#Matt Westelman
#5/2/18
#cocktailSort.py - implementing coctail sort

from random import randint
from time import time

N = 100 #how many numbers will be sorted

def mySort(A):
    swapped = True
    while swapped:
        swapped = False
        for i in range(0, len(A)-1):
            if A[i] > A[i+1]:
                A[i], A[i+1] = A[i+1], A[i]
                swapped = True
        if not swapped:
            break
        swapped = False
        for i in range(len(A)-2,-1,-1):
            if A[i] > A[i+1]:
                A[i], A[i+1] = A[i+1], A[i]
                swapped = True
    return A

if __name__ == '__main__':

    #make a list of N random numbers between 1 and N
    numbers = [0]*N
    for i in range(N):
        numbers[i] = randint(1,N)

    pythonSort = sorted(numbers) #Python's sort

    #time how long your sort takes
    t1 = time()
    numbers = mySort(numbers)
    t2 = time()

    #print whether the sort worked or not
    try:
        assert(numbers == pythonSort)
        print('Your sort took', t2-t1, 'seconds')
    except:
        print('Your sort did not work')


#!/usr/bin/env python
"""Displays calibration and guide offsets

History:
2011-02-16 ROwen
2011-02-18 ROwen    Removed the rotator axis since we never set rotator calib or guide offsets on the 3.5m.
"""
import Tkinter
import RO.CoordSys
import RO.StringUtil
import RO.Wdg
import TUI.TCC.TCCModel

_HelpURL = "Telescope/StatusWin.html#Offsets"
_DataWidth = 10

class AxisOffsetWdg (Tkinter.Frame):
    def __init__ (self, master=None, **kargs):
        """creates a new offset display frame

        Inputs:
        - master        master Tk widget -- typically a frame or window
        """
        Tkinter.Frame.__init__(self, master, **kargs)
        self.tccModel = TUI.TCC.TCCModel.getModel()
        self.isArc = False
        gr = RO.Wdg.Gridder(self, sticky="w")

        gr.gridWdg("Calib Off")
        gr.startNewCol()

        # just display az and alt offsets because there's no way to measure
        # rotator correction so it's never set
        MountLabels = ("Az", "Alt")

        # calib offset
        self.calibOffWdgSet = [
            RO.Wdg.DMSLabel(
                master = self,
                precision = 1,
                width = _DataWidth,
                helpText = "Calibration offset",
                helpURL = _HelpURL,
            )
            for ii in range(len(MountLabels))
        ]
        for ii, label in enumerate(MountLabels):
            wdgSet = gr.gridWdg (
                label = label,
                dataWdg = self.calibOffWdgSet[ii],
                units = RO.StringUtil.DMSStr,
            )
            wdgSet.labelWdg.configure(width=4, anchor="e")

        gr.startNewCol()
        gr.gridWdg(" Guide Off")
        gr.startNewCol()

        # guide offset
        self.guideOffWdgSet = [
            RO.Wdg.DMSLabel(
                master = self,
                precision = 1,
                width = _DataWidth,
                helpText = "Guide offset",
                helpURL = _HelpURL,
            )
            for ii in range(len(MountLabels))
        ]
        for ii, label in enumerate(MountLabels):
            wdgSet = gr.gridWdg (
                label = label,
                dataWdg = self.guideOffWdgSet[ii],
                units = RO.StringUtil.DMSStr,
            )
            wdgSet.labelWdg.configure(width=4, anchor="e")

        # allow the last+1 column to grow to fill the available space
        self.columnconfigure(gr.getMaxNextCol(), weight=1)

        self.tccModel.calibOff.addROWdgSet(self.calibOffWdgSet)
        self.tccModel.guideOff.addROWdgSet(self.guideOffWdgSet)

if __name__ == "__main__":
    import TestData

    tuiModel = TestData.tuiModel

    testFrame = OffsetWdg(tuiModel.tkRoot)
    testFrame.pack()

    dataList = (
        "ObjSys=ICRS, 0",
        "ObjInstAng=30.0, 0.0, 4494436859.66000",
        "ObjArcOff=-0.012, 0.0, 4494436859.66000, -0.0234, 0.000000, 4494436859.66000",
        "Boresight=0.0054, 0.0, 4494436859.66000, -0.0078, 0.000000, 4494436859.66000",
        "CalibOff=-0.001, 0.0, 4494436859.66000, 0.003, 0.000000, 4494436859.66000, -0.017, 0.000000, 4494436859.66000",
        "GuideOff=-0.003, 0.0, 4494436859.66000, -0.002, 0.000000, 4494436859.66000, 0.023, 0.000000, 4494436859.66000",
    )

    TestData.testDispatcher.dispatch(dataList)

    tuiModel.tkRoot.mainloop()


# program hitung syarat kelulusan

# input nilai

# Bahasa Indonesia
BahasaIndonesia = int(input('Nilai Bahasa Indonesia :'))
if(BahasaIndonesia < 0 or BahasaIndonesia > 100):
  print('Maaf input ada yang tidak valid')

# Matematika
Matematika = int(input('Nilai Matematika :'))
if(Matematika < 0 or Matematika > 100):
     print('Maaf input ada yang tidak valid')

# IPA
IPA = int(input('Nilai IPA :'))
if(IPA < 0 or IPA > 100):
    print('Maaf input ada yang tidak valid')

# Status Kelulusan
if(BahasaIndonesia > 60 and IPA > 60 and Matematika > 70):
  print('Status Kelulusan : LULUS')
else:
  print('Status Kelulusan : TIDAK LULUS')


import sys
import os
sys.path.insert(0, os.path.abspath('..'))
from vggish_input import waveform_to_examples
import numpy as np

SAMPLE_RATE = 44100
class AudioData:
    # def __init__(self):

    def normalize(self, arr):
        numerator = arr - np.min(arr)
        arr_min = np.min(arr)
        arr_max = np.max(arr)
        divisor = arr_max - arr_min
        if divisor > 0:
            #print('numerator', numerator, 'divisor', divisor)
            # assert divisor > 0, "Divisor is 0, Numerator: %f, Divisor: %f" % (numerator, divisor)
            normalized = numerator / divisor
            return normalized

        assert arr_max == arr_min, "arr has min and max that are not equal, min: %f, max: %f" % (arr_min, arr_max)
        arr.fill(0)
        return arr

    def getSamplesAsVggishInput(self, sample):
        sample = np.array(sample)
        sample = np.concatenate((sample, np.array([0] * 310)), axis=0)
        vggish_samples = waveform_to_examples(sample, SAMPLE_RATE)
        assert len(vggish_samples) > 0, "vggish returned 0, check your incoming samples"
        # print(vggish_samples)
        return self.normalize(np.array(vggish_samples))

# audioData = AudioData()


from qutip import *
from pylab import *
from scipy import *
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import time

# Count program run time
tstart = int(time.time())

# Define parameters
Nd =20            #number of basis states of phonon 1
omega1 = 1          #frequency of boson mode 1
omegaq=1            #frequency of qubit
g1=0.02              #coupling strength mode 1

# Define indintity for mode 1 and qubit
idaq = qeye(2);
idav = qeye(Nd);

# Define vibration operators
b1 = tensor(destroy(Nd),idaq);
# Define down operators for qubit
sm= tensor(idav,sigmam());
# Define spin operators.
sz=sm.dag()*sm-sm*sm.dag();

# Collapse operators decay for the mode 1, qubit and dephasing for the qubit. if none, leave the Collapse operators in mesolve empty with
kappa1=0.01
gammad=0.01
gammaf=0.001
C1 =sqrt(kappa1)*b1;
Dd1 = sqrt(gammad)*sm;
Ddf = sqrt(gammaf)*sz;

# Time list
t0 = 0.0
t1 = 100
Nt = 1000
times = linspace(t0,t1,Nt+1)        # 60 is very long time for the system

# Initial state
psi0 = tensor(basis(Nd,1),basis(2,1));

# Hamiltonian
H =0.5*omegaq*sz+omega1*b1.dag()*b1+g1*(b1.dag()+b1)*(sm+sm.dag());

# master equation slover
data = mesolve(H, psi0, times,[C1,Dd1,Ddf], [sm.dag()*sm])
#obtain the expection values
popexc=data.expect[0]

# save them in the .txt
data = open("data1.txt","w")     # Open(or create) a .txt document named by medata, as "write" style
for j in range(1000) :
    # Translate the data to "string" type
    tt   = '%f' %times[j]         # tt is short for t_txt, which represents txt data for times
    p1t  = '%f' %popexc[j]            # p1t is short for p1_txt
    data.write(tt+'	'+p1t+'	\n')    # write in the txt
data.close()

#plot the figure
fig, ax = plt.subplots(figsize=(8,6))
ax.plot(times, popexc)
ax.set_xlabel('Time')
ax.set_ylabel('P_ex')

ax.set_title('Excitation probabilty of qubit');
#show()

###########################################wigner fun#########################################################################

# obtain steady state
rho = steadystate(H,[C1,Dd1,Ddf])
#Calculating the time-dependent wignerfuction
xvec = linspace(-3,3,100)

ro = ptrace(rho, 0) #partial trace of density matrix
W_coherent = wigner(ro, xvec, xvec)
# another data save method----with python
file_data_store('wig.dat', W_coherent)

fig, axe =plt.subplots(figsize=(6,6))
axe.contourf(xvec, xvec, W_coherent, 100)
show()
###########################################wigner fun#########################################################################

# run time
tend = int(time.time())
tspent = tend - tstart
print('Total run time:',tspent,'\n')