from acitoolkit import Session, Tenant, Credentials

def main():
    """
    Main create tenant routine
    :return: None
    """
    # Get all the arguments
    description = 'It logs in to the APIC and will delete tenants named with the specified string.'
    creds = Credentials(['apic', 'nosnapshotfiles'], description)
    group = creds.add_mutually_exclusive_group()
    group.add_argument('--startswith', default=None,
                       help='String to match that starts the tenant name')
    group.add_argument('--endswith', default=None,
                       help='String to match that ends the tenant name')
    group.add_argument('--exactmatch', default=None,
                       help='String that exactly matches the tenant name')
    group.add_argument('--contains', default=None,
                       help='String that is contained in the tenant name')
    creds.add_argument('--force', action='store_true',
                       help='Attempt to remove the tenants without prompting for confirmation')
    args = creds.get()

    # Login to the APIC
    apic = Session(args.url, args.login, args.password)
    resp = apic.login()
    if not resp.ok:
        print('%% Could not login to APIC')

    # Get all of the Tenants
    tenants = Tenant.get(apic)

    # Find the list of Tenants to delete according to command line options
    tenants_to_delete = []
    for tenant in tenants:
        if args.startswith is not None:
            if tenant.name.startswith(args.startswith):
                tenants_to_delete.append(tenant)
        elif args.endswith is not None:
            if tenant.name.endswith(args.endswith):
                tenants_to_delete.append(tenant)
        elif args.exactmatch is not None:
            if args.exactmatch == tenant.name:
                tenants_to_delete.append(tenant)
        elif args.contains is not None:
            if args.contains in tenant.name:
                tenants_to_delete.append(tenant)

    # Query the user to be sure of deletion
    if not args.force:
        for tenant in tenants_to_delete:
            prompt = 'Delete tenant %s ? [y/N]' % tenant.name
            try:
                resp = raw_input(prompt)
            except NameError:
                resp = input(prompt)
            if not resp.lower().startswith('y'):
                tenants_to_delete.remove(tenant)
                print('Skipping tenant %s' % tenant.name)

    # Delete the tenants
    for tenant in tenants_to_delete:
        tenant.mark_as_deleted()
        resp = tenant.push_to_apic(apic)
        if resp.ok:
            print('Deleted tenant %s' % tenant.name)
        else:
            print('Could not delete tenant %s' % tenant.name)
            print(resp.text)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass


import logging

l = logging.getLogger("archinfo.arch_mips32")

try:
    import capstone as _capstone
except ImportError:
    _capstone = None

try:
    import keystone as _keystone
except ImportError:
    _keystone = None

try:
    import unicorn as _unicorn
except ImportError:
    _unicorn = None

from .arch import Arch, register_arch, Endness, Register
from .tls import TLSArchInfo

# FIXME: Tell fish to fix whatever he was storing in info['current_function']
# TODO: Only persist t9 in PIC programs

class ArchMIPS32(Arch):
    def __init__(self, endness=Endness.BE):
        super(ArchMIPS32, self).__init__(endness)
        if endness == Endness.BE:

            self.function_prologs = {
                br"\x27\xbd\xff[\x00-\xff]"                                          # addiu $sp, xxx
                br"\x3c\x1c[\x00-\xff][\x00-\xff]\x9c\x27[\x00-\xff][\x00-\xff]"     # lui $gp, xxx; addiu $gp, $gp, xxxx
            }
            self.function_epilogs = {
                br"\x8f\xbf[\x00-\xff]{2}([\x00-\xff]{4}){0,4}\x03\xe0\x00\x08"      # lw ra, off(sp); ... ; jr ra
            }
            self.qemu_name = 'mips'
            self.triplet = 'mips-linux-gnu'
            self.linux_name = 'mips'

    bits = 32
    vex_arch = "VexArchMIPS32"
    name = "MIPS32"
    ida_processor = 'mipsb'
    qemu_name = 'mipsel'
    linux_name = 'mipsel' # ???
    triplet = 'mipsel-linux-gnu'
    max_inst_bytes = 4
    ret_offset = 16
    syscall_num_offset = 16
    call_pushes_ret = False
    stack_change = -4
    branch_delay_slot = True
    sizeof = {'short': 16, 'int': 32, 'long': 32, 'long long': 64}
    if _capstone:
        cs_arch = _capstone.CS_ARCH_MIPS
        cs_mode = _capstone.CS_MODE_32 + _capstone.CS_MODE_LITTLE_ENDIAN
    if _keystone:
        ks_arch = _keystone.KS_ARCH_MIPS
        ks_mode = _keystone.KS_MODE_32 + _keystone.KS_MODE_LITTLE_ENDIAN
    uc_arch = _unicorn.UC_ARCH_MIPS if _unicorn else None
    uc_mode = (_unicorn.UC_MODE_32 + _unicorn.UC_MODE_LITTLE_ENDIAN) if _unicorn else None
    uc_const = _unicorn.mips_const if _unicorn else None
    uc_prefix = "UC_MIPS_" if _unicorn else None
    function_prologs = {
        br"[\x00-\xff]\xff\xbd\x27",                                         # addiu $sp, xxx
        br"[\x00-\xff][\x00-\xff]\x1c\x3c[\x00-\xff][\x00-\xff]\x9c\x27"     # lui $gp, xxx; addiu $gp, $gp, xxxx
    }
    function_epilogs = {
        br"[\x00-\xff]{2}\xbf\x8f([\x00-\xff]{4}){0,4}\x08\x00\xe0\x03"      # lw ra, off(sp); ... ; jr ra
    }

    ret_instruction = b"\x08\x00\xE0\x03" + b"\x25\x08\x20\x00"
    nop_instruction = b"\x00\x00\x00\x00"
    instruction_alignment = 4
    register_list = [
        Register(name='zero', size=4, alias_names=('r0',)),
        Register(name='at', size=4, alias_names=('r1',),
                 general_purpose=True),
        Register(name='v0', size=4, alias_names=('r2',),
                 general_purpose=True, linux_entry_value='ld_destructor'),
        Register(name='v1', size=4, alias_names=('r3',),
                 general_purpose=True),
        Register(name='a0', size=4, alias_names=('r4',),
                 general_purpose=True, argument=True),
        Register(name='a1', size=4, alias_names=('r5',),
                 general_purpose=True, argument=True),
        Register(name='a2', size=4, alias_names=('r6',),
                 general_purpose=True, argument=True),
        Register(name='a3', size=4, alias_names=('r7',),
                 general_purpose=True, argument=True),
        Register(name='t0', size=4, alias_names=('r8',),
                 general_purpose=True),
        Register(name='t1', size=4, alias_names=('r9',),
                 general_purpose=True),
        Register(name='t2', size=4, alias_names=('r10',),
                 general_purpose=True),
        Register(name='t3', size=4, alias_names=('r11',),
                 general_purpose=True),
        Register(name='t4', size=4, alias_names=('r12',),
                 general_purpose=True),
        Register(name='t5', size=4, alias_names=('r13',),
                 general_purpose=True),
        Register(name='t6', size=4, alias_names=('r14',),
                 general_purpose=True),
        Register(name='t7', size=4, alias_names=('r15',),
                 general_purpose=True),
        Register(name='s0', size=4, alias_names=('r16',),
                 general_purpose=True),
        Register(name='s1', size=4, alias_names=('r17',),
                 general_purpose=True),
        Register(name='s2', size=4, alias_names=('r18',),
                 general_purpose=True),
        Register(name='s3', size=4, alias_names=('r19',),
                 general_purpose=True),
        Register(name='s4', size=4, alias_names=('r20',),
                 general_purpose=True),
        Register(name='s5', size=4, alias_names=('r21',),
                 general_purpose=True),
        Register(name='s6', size=4, alias_names=('r22',),
                 general_purpose=True),
        Register(name='s7', size=4, alias_names=('r23',),
                 general_purpose=True),
        Register(name='t8', size=4, alias_names=('r24',),
                 general_purpose=True),
        Register(name='t9', size=4, alias_names=('r25',),
                 general_purpose=True, persistent=True),
        Register(name='k0', size=4, alias_names=('r26',),
                 general_purpose=True),
        Register(name='k1', size=4, alias_names=('r27',),
                 general_purpose=True),
        Register(name='gp', size=4, alias_names=('r28',),
                 persistent=True),
        Register(name='sp', size=4, alias_names=('r29',),
                 default_value=(Arch.initial_sp, True, 'global')),
        Register(name='s8', size=4, alias_names=('r30', 'fp', 'bp'),
                 general_purpose=True),
        Register(name='ra', size=4, alias_names=('r31', 'lr'),
                 general_purpose=True, persistent=True, linux_entry_value=0),
        Register(name='pc',  size=4, alias_names=('ip',)),
        Register(name='hi',  size=4, general_purpose=True),
        Register(name='lo',  size=4, general_purpose=True),
        Register(name='f0',  size=8, floating_point=True, subregisters=[('f0_lo', 0, 4)]),
        Register(name='f1',  size=8, floating_point=True, subregisters=[('f1_lo', 0, 4)]),
        Register(name='f2',  size=8, floating_point=True, subregisters=[('f2_lo', 0, 4)]),
        Register(name='f3',  size=8, floating_point=True, subregisters=[('f3_lo', 0, 4)]),
        Register(name='f4',  size=8, floating_point=True, subregisters=[('f4_lo', 0, 4)]),
        Register(name='f5',  size=8, floating_point=True, subregisters=[('f5_lo', 0, 4)]),
        Register(name='f6',  size=8, floating_point=True, subregisters=[('f6_lo', 0, 4)]),
        Register(name='f7',  size=8, floating_point=True, subregisters=[('f7_lo', 0, 4)]),
        Register(name='f8',  size=8, floating_point=True, subregisters=[('f8_lo', 0, 4)]),
        Register(name='f9',  size=8, floating_point=True, subregisters=[('f9_lo', 0, 4)]),
        Register(name='f10', size=8, floating_point=True, subregisters=[('f10_lo', 0, 4)]),
        Register(name='f11', size=8, floating_point=True, subregisters=[('f11_lo', 0, 4)]),
        Register(name='f12', size=8, floating_point=True, subregisters=[('f12_lo', 0, 4)]),
        Register(name='f13', size=8, floating_point=True, subregisters=[('f13_lo', 0, 4)]),
        Register(name='f14', size=8, floating_point=True, subregisters=[('f14_lo', 0, 4)]),
        Register(name='f15', size=8, floating_point=True, subregisters=[('f15_lo', 0, 4)]),
        Register(name='f16', size=8, floating_point=True, subregisters=[('f16_lo', 0, 4)]),
        Register(name='f17', size=8, floating_point=True, subregisters=[('f17_lo', 0, 4)]),
        Register(name='f18', size=8, floating_point=True, subregisters=[('f18_lo', 0, 4)]),
        Register(name='f19', size=8, floating_point=True, subregisters=[('f19_lo', 0, 4)]),
        Register(name='f20', size=8, floating_point=True, subregisters=[('f20_lo', 0, 4)]),
        Register(name='f21', size=8, floating_point=True, subregisters=[('f21_lo', 0, 4)]),
        Register(name='f22', size=8, floating_point=True, subregisters=[('f22_lo', 0, 4)]),
        Register(name='f23', size=8, floating_point=True, subregisters=[('f23_lo', 0, 4)]),
        Register(name='f24', size=8, floating_point=True, subregisters=[('f24_lo', 0, 4)]),
        Register(name='f25', size=8, floating_point=True, subregisters=[('f25_lo', 0, 4)]),
        Register(name='f26', size=8, floating_point=True, subregisters=[('f26_lo', 0, 4)]),
        Register(name='f27', size=8, floating_point=True, subregisters=[('f27_lo', 0, 4)]),
        Register(name='f28', size=8, floating_point=True, subregisters=[('f28_lo', 0, 4)]),
        Register(name='f29', size=8, floating_point=True, subregisters=[('f29_lo', 0, 4)]),
        Register(name='f30', size=8, floating_point=True, subregisters=[('f30_lo', 0, 4)]),
        Register(name='f31', size=8, floating_point=True, subregisters=[('f31_lo', 0, 4)]),
        Register(name='fir', size=4, floating_point=True),
        Register(name='fccr', size=4, floating_point=True),
        Register(name='fexr', size=4, floating_point=True),
        Register(name='fenr', size=4, floating_point=True),
        Register(name='fcsr', size=4, floating_point=True),
        Register(name='ulr', size=4),
        Register(name='emnote', size=4, artificial=True),
        Register(name='cmstart', size=4),
        Register(name='cmlen', size=4),
        Register(name='nraddr', size=4),
        Register(name='cond', size=4),
        Register(name='dspcontrol', size=4),
        Register(name='ac0', size=8),
        Register(name='ac1', size=8),
        Register(name='ac2', size=8),
        Register(name='ac3', size=8),
        Register(name='cp0_status', size=4),
        Register(name='ip_at_syscall', size=4, artificial=True),
    ]

    # see https://github.com/radare/radare/blob/master/src/include/elf/mips.h
    dynamic_tag_translation = {
        0x70000001: 'DT_MIPS_RLD_VERSION',
        0x70000002: 'DT_MIPS_TIME_STAMP',
        0x70000003: 'DT_MIPS_ICHECKSUM',
        0x70000004: 'DT_MIPS_IVERSION',
        0x70000005: 'DT_MIPS_FLAGS',
        0x70000006: 'DT_MIPS_BASE_ADDRESS',
        0x70000007: 'DT_MIPS_MSYM',
        0x70000008: 'DT_MIPS_CONFLICT',
        0x70000009: 'DT_MIPS_LIBLIST',
        0x7000000a: 'DT_MIPS_LOCAL_GOTNO',
        0x7000000b: 'DT_MIPS_CONFLICTNO',
        0x70000010: 'DT_MIPS_LIBLISTNO',
        0x70000011: 'DT_MIPS_SYMTABNO',
        0x70000012: 'DT_MIPS_UNREFEXTNO',
        0x70000013: 'DT_MIPS_GOTSYM',
        0x70000014: 'DT_MIPS_HIPAGENO',
        0x70000016: 'DT_MIPS_RLD_MAP',
        0x70000017: 'DT_MIPS_DELTA_CLASS',
        0x70000018: 'DT_MIPS_DELTA_CLASS_NO',
        0x70000019: 'DT_MIPS_DELTA_INSTANCE',
        0x7000001a: 'DT_MIPS_DELTA_INSTANCE_NO',
        0x7000001b: 'DT_MIPS_DELTA_RELOC',
        0x7000001c: 'DT_MIPS_DELTA_RELOC_NO',
        0x7000001d: 'DT_MIPS_DELTA_SYM',
        0x7000001e: 'DT_MIPS_DELTA_SYM_NO',
        0x70000020: 'DT_MIPS_DELTA_CLASSSYM',
        0x70000021: 'DT_MIPS_DELTA_CLASSSYM_NO',
        0x70000022: 'DT_MIPS_CXX_FLAGS',
        0x70000023: 'DT_MIPS_PIXIE_INIT',
        0x70000024: 'DT_MIPS_SYMBOL_LIB',
        0x70000025: 'DT_MIPS_LOCALPAGE_GOTIDX',
        0x70000026: 'DT_MIPS_LOCAL_GOTIDX',
        0x70000027: 'DT_MIPS_HIDDEN_GOTIDX',
        0x70000028: 'DT_MIPS_PROTECTED_GOTIDX',
        0x70000029: 'DT_MIPS_OPTIONS',
        0x7000002a: 'DT_MIPS_INTERFACE',
        0x7000002b: 'DT_MIPS_DYNSTR_ALIGN',
        0x7000002c: 'DT_MIPS_INTERFACE_SIZE',
        0x7000002d: 'DT_MIPS_RLD_TEXT_RESOLVE_ADDR',
        0x7000002e: 'DT_MIPS_PERF_SUFFIX',
        0x7000002f: 'DT_MIPS_COMPACT_SIZE',
        0x70000030: 'DT_MIPS_GP_VALUE',
        0x70000031: 'DT_MIPS_AUX_DYNAMIC',
        0x70000032: 'DT_MIPS_PLTGOT'

    }
    got_section_name = '.got'
    ld_linux_name = 'ld.so.1'
    elf_tls = TLSArchInfo(1, 8, [], [0], [], 0x7000, 0x8000)

register_arch([r'mipsel|mipsle'], 32, Endness.LE , ArchMIPS32)
register_arch([r'.*mips.*'], 32, 'any' , ArchMIPS32)


import json
import requests
import time
import sys
from datetime import datetime

# THERE IS NO NEED TO EDIT THE SCRIPT. RUN THE SCRIPT AS IS!

# Function to display banner
def display_banner():
    banner = """

██╗░░██╗███████╗███╗░░██╗  ██████╗░██╗░░░░░░█████╗░░█████╗░██╗░░██╗░██████╗
╚██╗██╔╝██╔════╝████╗░██║  ██╔══██╗██║░░░░░██╔══██╗██╔══██╗██║░██╔╝██╔════╝
░╚███╔╝░█████╗░░██╔██╗██║  ██████╦╝██║░░░░░██║░░██║██║░░╚═╝█████═╝░╚█████╗░
░██╔██╗░██╔══╝░░██║╚████║  ██╔══██╗██║░░░░░██║░░██║██║░░██╗██╔═██╗░░╚═══██╗
██╔╝╚██╗███████╗██║░╚███║  ██████╦╝███████╗╚█████╔╝╚█████╔╝██║░╚██╗██████╔╝
╚═╝░░╚═╝╚══════╝╚═╝░░╚══╝  ╚═════╝░╚══════╝░╚════╝░░╚════╝░╚═╝░░╚═╝╚═════╝░
    """
    print(banner)

# Function to query RPC
def send_rpc_request(method, params=None, request_id=1):
    headers = {'Content-Type': 'application/json'}
    payload = {
        "jsonrpc": "2.0",
        "id": request_id,
        "method": method,
        "params": params if params is not None else []
    }

    response = requests.post(RPC_URL, headers=headers, json=payload)
    if response.status_code == 200:
        return response.json()
    else:
        return None

# Constants for RPC and Custom Server URLs
RPC_URL = "http://xenminer.mooo.com:5555"
CUSTOM_SERVER_URL = "http://xenminer.mooo.com"

# Function to query custom server
def send_custom_request(endpoint, params=None):
    url = f"{CUSTOM_SERVER_URL}/{endpoint}"
    response = requests.get(url, params=params)
    if response.status_code == 200:
        return response.json()
    else:
        return None

# Display banner
display_banner()

# Get account address from user
print(f"Enter ENS or wallet address.")
account = input("Please enter your XenBlocks account address: ").lower()

while True:
    # Initialize variables
    total_network_blocks = 0
    total_account_blocks = 0
    balance_xblk = 0

    # Query total number of blocks in the network
    response = send_rpc_request("eth_blockNumber")
    if response:
        total_network_blocks = int(response.get('result'), 16)  # Convert from hex to decimal

    # Query total number of blocks for the account
    response = send_custom_request("total_blocks2", {"account": account})
    if response:
        total_account_blocks = response.get('total_blocks')

    # Query balance of the account
    response = send_rpc_request("eth_getBalance", [account])
    if response:
        balance_wei = int(response.get('result'), 16)  # Convert from hex to decimal
        balance_xblk = balance_wei / 10**18  # Convert from Wei to X.BLK

    # Display all information
    print("\n🔥🔥🔥 XENBlock Mon 🔥🔥🔥")
    print(f"🌐 Network Name: XenBLOCKs")
    print(f"💻 RPC URL: {RPC_URL}")
    print(f"🕒 Current Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print(f"🔗 Chain ID: 108016")
    print(f"💰 Currency: X.BLK")
    print(f"\n👤 Account Address: {account}")
    print(f"📊 Total number of blocks in the network: \033[93m{total_network_blocks}\033[0m")
    print(f"📈 Total number of blocks for account {account}: \033[93m{total_account_blocks}\033[0m")
    print(f"💸 Balance of account {account}: \033[93m{balance_xblk} X.BLK\033[0m")
    print("◼" * 30)

    # Wait for 30 seconds before the next update
    print("Created by TreeCityWes.eth. Press CTRL+C to Exit.")

    # Countdown for next update on the same line
    sys.stdout.write("Next update in: ")
    for i in range(30, 0, -1):
        sys.stdout.write(f"\rNext update in: {i} seconds")
        sys.stdout.flush()
        time.sleep(1)
    print("\rRefreshing now... ")


import config
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from pprint import pprint

scope = config.scope
creds = ServiceAccountCredentials.from_json_keyfile_name('./goog_secretclient.json', scope)
client = gspread.authorize(creds)

sheet1 = client.open('IRA').sheet1

results = sheet1.get_all_records()

current_rows = len(sheet1.get_all_values())
print(current_rows)

class Writer:

	#Cells A(ROW):F(ROW)
	def writeOptionInfo(self, symbol, open_date, exp_date, order_type, action, curr_price):
		range = self.locateCells(1)
		sheet1.update(range, [[symbol, open_date, exp_date, order_type, action, curr_price]])

	#Cells J(ROW):L(ROW)
	def writeTransactionCost(self, strike, cost, count):
		range = self.locateCells(2)
		sheet1.update(range, [[strike, cost, count]])

	#Cells P(ROW):R(ROW) & W(ROW):X(ROW)
	def writeClosingInfo(self, fees, exit_price, close_date):
		ranges = self.locateCells(3)
		sheet1.update(ranges[0], [[' ' , fees, exit_price, close_date]])
		sheet1.update(ranges[1], [['Close', 'TD']])

	def findStrike(self, option, strike):
		if option == 'CALL':
			chunks = strike.split('C')
			return chunks[len(chunks)-1]
		else:
			chunks = strike.split('P')
			return chunks[len(chunks)-1]

	def locateCells(self, section):

		#locate empty space for option info
		emptyRow = str(current_rows + 1)
		if section == 1:
			cellRange = 'A' + emptyRow + ':F' + emptyRow
			return cellRange

		#locate empty space for transaction info
		elif section == 2:
			cellRange = 'J' + emptyRow + ':L' + emptyRow
			return cellRange

		#locate empty space for closing info
		else:
			cellRange1 = 'O' + emptyRow + ':R' + emptyRow
			cellRange2 = 'W' + emptyRow + ':X' + emptyRow
			return cellRange1, cellRange2


import pytest

# Required name-bound config file for pytest

def pytest_addoption(parser):
    parser.addoption("--loadtestcase", default="test_32", action="store")
    parser.addoption("--rundataflow", default="execapp.sh", action="store")
    parser.addoption("--runperf", default=False, action="store_true", help="run perf tests")
    parser.addoption("--runslow", action="store_true", default=False, help="run slow tests")
    parser.addoption("--runprecheckin", action="store_true", default=False, help="run precheckin tests")
    parser.addoption("--runrelease", action="store_true", default=False, help="run release tests")
    parser.addoption("--bucket", action="store", default="xcfield", help="bucket")

@pytest.fixture(scope='session')
def loadtestcase(request):
    name_value = request.config.option.loadtestcase
    if name_value is None:
        pytest.skip()
    return name_value

@pytest.fixture(scope='session')
def rundataflow(request):
    name_value = request.config.option.rundataflow
    if name_value is None:
        pytest.skip()
    return name_value

@pytest.fixture(scope='session')
def runperf(request):
    return request.config.option.runperf

@pytest.fixture(scope='session')
def bucket(request):
    return request.config.option.bucket

def pytest_configure(config):
    config.addinivalue_line("markers", "slow: mark test as slow to run")
    config.addinivalue_line("markers", "precheckin: mark test as prechecking to run")
    config.addinivalue_line("markers", "release: mark test as release to run")

def pytest_collection_modifyitems(config, items):
    skip_test = pytest.mark.skip()
    if not config.getoption("--runslow"):
        # --runslow given in cli: do not skip slow tests
        for item in items:
            if "slow" in item.keywords:
                item.add_marker(skip_test)


class Solution:
    def checkSubarraySum(self, nums: List[int], k: int) -> bool:
        visited = {0: -1}
        subsum = 0
        for i in range(len(nums)):
            subsum = (subsum + nums[i]) % k
            if subsum in visited:
                if i - visited[subsum] > 1:
                    return True
            else:
                visited[subsum] = i
        return False


import logging
import pdb

def plot_rti(sTime, rad, eTime=None, bmnum=7, fileType='fitacf',
                    params=['power','velocity','width'], scales=[], channel=None,
                    coords='gate', colors='lasse', yrng=-1, gsct=False,
                    low_gray=False, show=True, filtered=False,
                    fileName=None, txfreq_lims=None, myFile=None,
                    xtick_size=9, ytick_size=9,
                    xticks=None, axvlines=None,
                    plot_terminator=False, data_dict=None):

    """ Create an rti plot for a specified radar and time period.

    Parameters
    ----------
    sTime : datetime
        a datetime object indicating the start time which you would like
        to plot
    rad : str
        the 3 letter radar code, e.g. 'bks'
    eTime : Optional[datetime]
        a datetime object indicating th end time you would like plotted.
        If this is None, 24 hours will be plotted.  default = None.
    bmnum : Optional[int]
        The beam to plot.  default: 7
    fileType : Optional[str]
        The file type to be plotted, one of ['fitex', 'fitacf', 'lmfit'].
        default = 'fitex'.
    params : Optional[list]
        a list of the fit parameters to plot, allowable values are:
        ['velocity', 'power', 'width', 'elevation', 'phi0'].  default:
        ['velocity', 'power', 'width']
    scales : Optional[list]
        a list of the min/max values for the color scale for each param.
        If omitted, default scales will be used.  If present, the list
        should be n x 2 where n is the number of elements in the params
        list.  Use an empty list for default range, e.g. [[-250,300],[],[]].
        default: [[-200,200], [0,30],[0,150]]
    channel : Optional[char]
        the channel you wish to plot, e.g. 'a', 'b', 'c', ...  default: 'a'
    coords : Optional[str]
        the coordinates to use for the y axis.  The allowable values are
        'gate', 'rng', 'geo', 'mag' default: 'gate'
    colors : Optional[str]
        a string indicating what color bar to use, valid inputs are
        'lasse' or 'aj'. Also can be a list of matplotlib colormaps names,
        for example ['jet','jet','jet'] if len(param)==3. default: 'lasse'.
    yrng : Optional[list or -1]
        a list indicating the min and max values for the y axis in the
        chosen coordinate system, or a -1 indicating to plot everything.
        default: -1.
    gsct : Optional[boolean]
        a flag indicating whether to plot ground scatter as gray. default:
        False (ground scatter plotted normally)
    low_gray : Optional[boolean]
        a flag indicating whether to plot low velocity scatter as gray.
        default: False (low velocity scatter plotted normally)
    show : Optional[boolean]
        a flag indicating whether to display the figure on the screen.
        This can cause problems over ssh.  default = True
    retfig : Optional[boolean]
        a flag indicating that you want the figure to be returned from
        the function.  Only the last figure in the list of frequency bands
        will be returned.  default = False
    filtered : Optional[boolean]
        a flag indicating whether to boxcar filter the data.  default:
        False (no filter)
    fileName : Optional[string]
        If you want to plot for a specific file, indicate the name of the
        file as fileName.  Include the type of the file in custType.
    txfreq_lims : Optional[list]
        a list of the min/max values for the transmitter frequencies in
        kHz.  If omitted, the default band will be used.  If more than
        one band is specified, retfig will cause only the last one to be
        returned.  default: [[8000,20000]]
    myFile : Optional[pydarn.sdio.radDataTypes.radDataPtr]
        contains the pipeline to the data we want to plot. If specified,
        data will be plotted from the file pointed to by myFile. default: None
    xtick_size : Optional[int]
        fontsize of xtick labels
    ytick_size : Optional[int]
        fontsize of ytick labels
    xticks : Optional[list]
        datetime.datetime objects indicating the location of xticks
    axvlines : Optoinal[list]
        datetime.datetime objects indicating the location vertical lines
        marking the plot
    plot_terminator : Optional[boolean]
        Overlay the day/night terminator.
    data_dict : Optinal[dict, default value is None]
        This takes the output of read_data function in this module.

    Returns
    -------
    A figure object

    Example
    -------
        import datetime as dt
        pydarn.plotting.rti.plot_rti(dt.datetime(2013,3,16), 'bks',
                                     eTime=dt.datetime(2013,3,16,14,30),
                                     bmnum=12, fileType='fitacf',
                                     scales=[[-500,500],[],[]], coords='geo',
                                     colors='aj', filtered=True, show=True)

    Written by AJ 20121002
    Modified by Matt W. 20130715
    Modified by Nathaniel F. 20131031 (added plot_terminator)
    Modified by ASR 20150917 (refactored)
    Modified by Muhamamd 20160728

    """

    import os
    from davitpy import pydarn
    from davitpy import utils
    import numpy as np
    from datetime import datetime, timedelta
    from matplotlib import pyplot
    from matplotlib.dates import DateFormatter
    import matplotlib.cm as cm

    #Time how long this is going to take
    timing_start = datetime.now()

    #NOTE TO DEVS: List of available params. Can be simply expanded
    #as more parameters are added to SuperDARN data set (like index
    #of refraction)
    available_params = ['power','velocity','width','elevation','phi0','velocity_error']
    default_scales = [[0,30],[-200,200],[0,150],[0,50],[-np.pi, np.pi],[0,200]]

    available_text = 'Allowable parameters are '
    for p in available_params:
        available_text = available_text + p + ', '
    available_text = available_text[:-2]

    #Check the inputs
    assert(isinstance(sTime, datetime)), logging.error(
        'sTime must be a datetime object')
    assert(isinstance(rad, str) and len(rad) == 3), logging.error(
        'rad must be a string 3 chars long')
    assert(isinstance(eTime, datetime) or
           eTime is None), (
        logging.error('eTime must be a datetime object or None'))
    if eTime is None:
        eTime = sTime + timedelta(days=1)
    assert(sTime < eTime), logging.error("eTime must be greater than sTime!")
    assert(coords == 'gate' or coords == 'rng' or coords == 'geo' or
           coords == 'mag'), logging.error("coords must be one of 'gate', "
                                           "'rng', 'geo', 'mag'")
    assert(isinstance(bmnum, int)), logging.error('beam must be integer')
    assert(0 < len(params) < 6), (
        logging.error('must input between 1 and 5 params in LIST form'))
    for i in range(0, len(params)):
        assert(params[i] in available_params), (
            logging.error(available_text))
    for i in range(0, len(scales)):
        assert(isinstance(scales[i], list)), (
            logging.error('each item in scales must be a list of upper and '
                          'lower bounds on paramaters.'))
    assert(scales == [] or
           len(scales) == len(params)), (
        logging.error('if present, scales must have same number of elements '
                      'as params'))
    assert(yrng == -1 or
           (isinstance(yrng, list) and
            yrng[0] <= yrng[1])), (
        logging.error('yrng must equal -1 or be a list with the 2nd element '
                      'larger than the first'))
    assert((colors == 'lasse' or colors == 'aj')) or isinstance(colors,list), (
        logging.error("Valid inputs for color are 'lasse' and 'aj' or a list of matplotlib colormaps"))

    assert( (isinstance(txfreq_lims,list) and len(txfreq_lims)==2) or
            isinstance(txfreq_lims,type(None))), (
        logging.error("txfreq_lims must be a list with the start and end frequencies") )

    # Assign any default color scale parameter limits.
    tscales = []
    for i in range(0, len(params)):
        if(scales == [] or scales[i] == []):
            if(params[i] in available_params):
                ind = available_params.index(params[i])
                tscales.append(default_scales[ind])
        else: tscales.append(scales[i])
    scales = tscales

    # Assign default frequency band.
    if txfreq_lims is None:
        tband = [8000, 20000]
    else:
        assert(txfreq_lims[0] < txfreq_lims[1]), (
            logging.error("Starting frequency must be less "
                          "than ending frequency!"))
        tband = txfreq_lims

    # Open the file if a pointer was not given to us
    # if fileName is specified then it will be read.
    if not myFile:
        from davitpy.pydarn.sdio import radDataOpen
        myFile = radDataOpen(sTime, rad, eTime, channel=channel, bmnum=bmnum,
                             fileType=fileType, filtered=filtered,
                             fileName=fileName)

        # Check that we have data available now that we may have tried
        # to read it using radDataOpen.
        if myFile is None:
            logging.error('No files available for the requested '
                          'time/radar/filetype combination')
            return None

    # Make sure that we will only plot data for the time range specified
    # by sTime and eTime.
    if myFile.sTime <= sTime and myFile.eTime > sTime and myFile.eTime >= eTime:
        myFile.sTime = sTime
        myFile.eTime = eTime
    else:
        # If the times range is not covered by the file, warn the user.
        logging.warning('Data not available in myFile for the whole of sTime to eTime!')

    # Finally we can start reading the data file
    myBeam = myFile.readRec()
    if myBeam is None:
        logging.error('Problem reading the data.')
        return None

    # Now read the data that we need to make the plots
    if data_dict is None:
        data_dict = read_data(myFile, bmnum, params, tband)
    else:
        # Make sure that we only plot data for the time range specified
        selected_indices = [x for x in xrange(len(data_dict['datetime'])) if \
                (data_dict['datetime'][x] >= sTime and data_dict['datetime'][x] <= eTime)]
        sindx = selected_indices[0]
        eindx = selected_indices[-1]
        for keywrd in data_dict.keys():
            data_dict[keywrd] = data_dict[keywrd][sindx:eindx+1]

    # Check to ensure that data exists for the requested frequency
    # band else continue on to the next range of frequencies
    if len(data_dict['freq']) == 0:
        logging.error('No data found in frequency range ' +
                        str(tbands[0]) + ' kHz to ' +
                        str(tbands[1]) + ' kHz')
        return None

    # Create a figure.
    rti_fig = pyplot.figure(figsize=(11, 8.5))

    # Create the axes for noise, tx freq, and cpid.
    noise_pos = [.1, .88, .76, .06]
    freq_pos = [.1, .82, .76, .06]
    cpid_pos = [.1, .77, .76, .05]

    skynoise_ax = rti_fig.add_axes(noise_pos, label='sky')
    searchnoise_ax = rti_fig.add_axes(noise_pos, label='search',
                                      frameon=False)
    freq_ax = rti_fig.add_axes(freq_pos, label='freq')
    nave_ax = rti_fig.add_axes(freq_pos, label='nave', frameon=False)
    cpid_ax = rti_fig.add_axes(cpid_pos)

    # Give the plot a title.
    rti_title(rti_fig, sTime, rad, fileType, bmnum, eTime=eTime)

#    # Plot the sky noise.
#    plot_skynoise(skynoise_ax, data_dict['datetime'],
#                  data_dict['nsky'])
#    # Plot the search noise.
#    plot_searchnoise(searchnoise_ax, data_dict['datetime'],
#                        data_dict['nsch'])
    # plot the frequency bar.
    plot_freq(freq_ax, data_dict['datetime'],
                data_dict['freq'])
    # Plot the nave data.
    plot_nave(nave_ax, data_dict['datetime'],
                data_dict['nave'])
    # Plot the cpid bar
    plot_cpid(cpid_ax, data_dict['datetime'],
                data_dict['cpid'], data_dict['mode'])

    # Plot each of the parameter panels.
    figtop = .77
    if ((eTime - sTime) <= timedelta(days=1)) and \
            (eTime.day == sTime.day):
        figheight = .72 / len(params)
    elif ((eTime - sTime) > timedelta(days=1)) or \
            (eTime.day != sTime.day):
        figheight = .70 / len(params)

    for p in range(len(params)):
        # Use draw_axes to create and set formatting of the axes to
        # plot to.
        pos = [.1, figtop - figheight * (p + 1) + .02, .76,
                figheight - .02]
        ax = draw_axes(rti_fig, data_dict['datetime'], rad,
                       data_dict['cpid'], bmnum,
                       data_dict['nrang'],
                       data_dict['frang'], data_dict['rsep'],
                       p == len(params) - 1, yrng=yrng, coords=coords,
                       pos=pos, xtick_size=xtick_size,
                       ytick_size=ytick_size, xticks=xticks,
                       axvlines=axvlines)

        if(params[p] == 'velocity'): pArr = data_dict['vel']
        elif(params[p] == 'power'): pArr = data_dict['pow']
        elif(params[p] == 'width'): pArr = data_dict['wid']
        elif(params[p] == 'elevation'): pArr = data_dict['elev']
        elif(params[p] == 'phi0'): pArr = data_dict['phi0']
        elif(params[p] == 'velocity_error'):
            pArr = data_dict['velocity_error']
        if(pArr == []): continue

        # Generate the color map.

        if colors in ['aj','lasse']:
            cmap, norm, bounds = utils.plotUtils.genCmap(params[p], scales[p],
                                                         colors=colors,
                                                         lowGray=low_gray)
        else:
            from matplotlib import colors as mpl_colors
            norm = mpl_colors.Normalize(vmin=scales[p][0], vmax=scales[p][1])
            cmap = cm.get_cmap(colors[p])

        # Plot the data to the axis object.
        pcoll = rti_panel(ax,data_dict,pArr,gsct,rad,bmnum,coords,cmap,norm,
                          plot_terminator=plot_terminator)

        # Set xaxis formatting depending on amount of data plotted.
        if ((eTime - sTime) <= timedelta(days=1)) and \
                (eTime.day == sTime.day):
            ax.xaxis.set_major_formatter(DateFormatter('%H:%M'))
        elif ((eTime - sTime) > timedelta(days=1)) or \
                (eTime.day != sTime.day):
            ax.xaxis.set_major_formatter(DateFormatter('%d/%m/%y \n%H:%M'))
        ax.set_xlabel('UT')

        # Draw the colorbar.
        cb = utils.drawCB(rti_fig, pcoll, cmap, norm, map_plot=0,
                          pos=[pos[0] + pos[2] + .02, pos[1], 0.02,
                          pos[3]])

        if colors in ['aj','lasse']:
            # Label the colorbar.
            l = []
            # Define the colorbar labels.
            for i in range(0, len(bounds)):
                if(params[p] == 'phi0'):
                    ln = 4
                    if(bounds[i] == 0): ln = 3
                    elif(bounds[i] < 0): ln = 5
                    l.append(str(bounds[i])[:ln])
                    continue
                if((i == 0 and
                    (params[p] == 'velocity' or
                     params[p] == 'velocity_error')) or i == len(bounds) - 1):
                    l.append(' ')
                    continue
                l.append(str(int(bounds[i])))
            cb.ax.set_yticklabels(l)

            # Set colorbar ticklabel size.
            for t in cb.ax.get_yticklabels():
                t.set_fontsize(9)

        # Set colorbar label.
        if(params[p] == 'velocity'):
            cb.set_label('Velocity [m/s]', size=10)
        if(params[p] == 'grid'): cb.set_label('Velocity [m/s]', size=10)
        if(params[p] == 'power'): cb.set_label('SNR [dB]', size=10)
        if(params[p] == 'width'): cb.set_label('Spec Wid [m/s]', size=10)
        if(params[p] == 'elevation'): cb.set_label('Elev [deg]', size=10)
        if(params[p] == 'phi0'): cb.set_label('Phi0 [rad]', size=10)
        if(params[p] == 'velocity_error'):
            cb.set_label('Velocity Error [m/s]', size=10)

    if show:
        rti_fig.show()

    logging.info('plotting took:', datetime.now() - timing_start)

    return rti_fig

def draw_axes(myFig, times, rad, cpid, bmnum, nrang, frang, rsep, bottom,
              yrng=-1, coords='gate', pos=[.1, .05, .76, .72], xtick_size=9,
              ytick_size=9, xticks=None, axvlines=None):
    """ Draws empty axes for an rti plot.

    Parameters
    ----------
    myFig :
        the MPL figure we are plotting to
    times : list
        a list of datetime objects referencing the beam soundings
    rad : str
        3 letter radar code
    cpid : list
        list of the cpids or the beam soundings
    bmnum : int
        beam number being plotted
    nrang : list
        list of nrang for the beam soundings
    frang : list
        list of frang of the beam soundings
    rsep : list
        list of rsep of the beam soundings
    bottom : bool
        flag indicating if we are at the bottom of the figure
    yrng : Optional[list]
        range of y axis, -1=autoscale (default)
    coords : Optional[ ]
        y axis coordinate system, acceptable values are 'geo',
        'mag', 'gate', 'rng'
    pos : Optional[ ]
        position of the plot
    xtick_size : Optional[ ]
        fontsize of xtick labels
    ytick_size : Optional[ ]
        fontsize of ytick labels
    xticks : Optional[list]
        datetime.datetime objects indicating the location of xticks
    axvlines : Optional[list]
        datetime.datetime objects indicating the location vertical
        lines marking the plot

    Returns
    -------
    ax :
        an axes object

    Example
    -------
        ax = draw_axes(myFig,times,rad,cpid,beam,nrang,frang,rsep,0)

    Written by AJ 20121002
    Modified by ASR 20150917 (refactored)

    """

    from davitpy import pydarn
    from matplotlib.ticker import MultipleLocator,FormatStrFormatter
    from matplotlib.dates import SecondLocator,DateFormatter,date2num
    from matplotlib.lines import Line2D
    import numpy as np

    nrecs = len(times)
    # Add an axes object to the figure.
    ax = myFig.add_axes(pos)
    ax.yaxis.set_tick_params(direction='out')
    ax.xaxis.set_tick_params(direction='out')
    ax.yaxis.set_tick_params(direction='out', which='minor')
    ax.xaxis.set_tick_params(direction='out', which='minor')

    # Draw the axes.
    ax.plot_date(date2num(times), np.arange(len(times)),
                 fmt='w', tz=None, xdate=True, ydate=False, alpha=0.0)

    # Determine the yaxis min/max unless it's been specified
    if(yrng == -1):
        ymin, ymax = 99999999, -999999999
        if(coords != 'gate'):
            oldCpid = -99999999
            for i in range(len(cpid)):
                if(cpid[i] == oldCpid): continue
                oldCpid = cpid[i]
                if(coords == 'geo' or coords == 'mag'):
                    # HACK NOT SURE IF YOU CAN DO THIS(Formatting)!
                    site = pydarn.radar.network().getRadarByCode(rad) \
                        .getSiteByDate(times[i])
                    myFov = pydarn.radar.radFov.fov(site=site, ngates=nrang[i],
                                                    nbeams=site.maxbeam,
                                                    rsep=rsep[i],
                                                    coords=coords,
                                                    date_time=times[i])
                    if(myFov.latFull[bmnum].max() > ymax):
                        ymax = myFov.latFull[bmnum].max()
                    if(myFov.latFull[bmnum].min() < ymin):
                        ymin = myFov.latFull[bmnum].min()
                else:
                    ymin = 0
                    if(nrang[i] * rsep[i] + frang[i] > ymax):
                        ymax = nrang[i] * rsep[i] + frang[i]

        else:
            ymin, ymax = 0, max(nrang)
    else:
        ymin, ymax = yrng[0], yrng[1]

    # Format the xaxis.
    xmin = date2num(times[0])
    xmax = date2num(times[len(times) - 1])
    xrng = (xmax - xmin)
    inter = int(round(xrng / 6. * 86400.))
    inter2 = int(round(xrng / 24. * 86400.))
    ax.xaxis.set_minor_locator(SecondLocator(interval=inter2))
    ax.xaxis.set_major_locator(SecondLocator(interval=inter))

    # If axis is at bottom of figure, draw xticks.
    if(not bottom):
        for tick in ax.xaxis.get_major_ticks():
            tick.label.set_fontsize(0)
    else:
        if xticks is not None:
            ax.xaxis.set_ticks(xticks)

    if axvlines is not None:
        for line in axvlines:
            ax.axvline(line, color='0.25', ls='--')

        for tick in ax.xaxis.get_major_ticks():
            tick.label.set_fontsize(xtick_size)
        ax.xaxis.set_major_formatter(DateFormatter('%H:%M'))
        ax.xaxis.set_label_text('UT')

    # Set ytick size.
    for tick in ax.yaxis.get_major_ticks():
        tick.label.set_fontsize(ytick_size)
    # Format yaxis depending on coords.
    if(coords == 'gate'):
        ax.yaxis.set_label_text('Range gate', size=10)
        ax.yaxis.set_major_formatter(FormatStrFormatter('%d'))
        ax.yaxis.set_major_locator(MultipleLocator((ymax - ymin) / 5.))
        ax.yaxis.set_minor_locator(MultipleLocator((ymax - ymin) / 25.))
    elif(coords == 'geo' or coords == 'mag'):
        if(coords == 'mag'):
            ax.yaxis.set_label_text('Mag Lat [deg]', size=10)
        else:
            ax.yaxis.set_label_text('Geo Lat [deg]', size=10)
    elif(coords == 'rng'):
        ax.yaxis.set_label_text('Slant Range [km]', size=10)
        ax.yaxis.set_major_formatter(FormatStrFormatter('%d'))
        ax.yaxis.set_major_locator(MultipleLocator(1000))
        ax.yaxis.set_minor_locator(MultipleLocator(250))
    ax.set_ylim(bottom=ymin, top=ymax)

    return ax

def rti_title(fig, sTime, rad, fileType, beam, eTime=None, xmin=.1, xmax=.86):
    """Draws title for an rti plot.

    Parameters
    ----------
    fig : matplotlib.figure.Figure
        a matplotlib.figure.Figure object
    sTime : datetime
        the start time for the data being plotted as a datetime object
    rad : str
        the 3 letter radar code
    fileType : str
        the file type being plotted
    beam : int
        the beam number being plotted
    eTime : Optional[datetime]
        the end time for the data being plotted as a datetime object
    xmin : Optional[ ]
        minimum x value o the plot in page coords
    xmax : Optional[ ]
        maximum x value o the plot in page coords

    Returns
    -------
    Nothing.

    Example
    -------
        import datetime as dt
        from matplotlib import pyplot
        fig = pyplot.figure()
        rti_title(fig,dt.datetime(2011,1,1),'bks','fitex',7)

    Written by AJ 20121002
    Modified by ASR 20150916

    """
    from davitpy import pydarn
    from datetime import timedelta
    import calendar

    # Obtain the davitpy.pydarn.radar.radStruct.radar object for rad.
    r = pydarn.radar.network().getRadarByCode(rad)

    # Plot the main title
    fig.text(xmin, .95, r.name + '  (' + fileType + ')', ha='left', weight=550)

    # Determine what time information should be plotted in the secondary title
    if ((eTime is not None) and
        (((eTime - sTime) > timedelta(days=1)) or
         (eTime.day != sTime.day))):
        title_text = str(sTime.day) + '/' \
            + calendar.month_name[sTime.month][:3] + '/' \
            + str(sTime.year) + ' - ' + str(eTime.day) + '/' \
            + calendar.month_name[eTime.month][:3] + '/' \
            + str(eTime.year)

    else:
        title_text = str(sTime.day) + '/' \
            + calendar.month_name[sTime.month][:3] + '/' \
            + str(sTime.year)

    # Plot the secondary title.
    fig.text((xmin + xmax) / 2., .95, title_text, weight=550,
             size='large', ha='center')
    fig.text(xmax, .95, 'Beam ' + str(beam), weight=550, ha='right')

def plot_cpid(ax, times, cpid, mode):
    """Plots control program ID (cpid) panel at position pos.

    Parameters
    ----------
    ax :
        a MPL axis object to plot to
    times : list
        a list of the times of the beam soundings
    cpid : list
        a list of the cpids of th beam soundings
    mode : list
        a list of the ifmode param

    Returns
    -------
    Nothing.

    Example
    -------
        plot_cpid(ax,times,cpid,mode)

    Written by AJ 20121002
    Modified by ASR 20150916

    """
    from davitpy import pydarn
    from matplotlib.ticker import MultipleLocator
    from matplotlib.dates import SecondLocator
    from matplotlib.dates import date2num
    import numpy as np
    oldCpid = -9999999

    # Format the yaxis.
    ax.yaxis.tick_left()
    ax.yaxis.set_tick_params(direction='out')
    ax.set_ylim(bottom=0, top=1)
    ax.yaxis.set_minor_locator(MultipleLocator(1))
    ax.yaxis.set_tick_params(direction='out', which='minor')

    # Draw the axes.
    ax.plot_date(date2num(times), np.arange(len(times)),
                 fmt='w', tz=None, xdate=True, ydate=False, alpha=0.0)

    # Label the CPIDs.
    for i in range(0, len(times)):
        if(cpid[i] != oldCpid):
            ax.plot_date([date2num(times[i]),date2num(times[i])],
                         [0, 1], fmt='k-', tz=None, xdate=True, ydate=False)
            oldCpid = cpid[i]
            s = ' ' + pydarn.radar.radUtils.getCpName(oldCpid)
            istr = ' '
            if(mode[i] == 1): istr = ' IF'
            if(mode == 0): istr = ' RF'
            ax.text(times[i], .5, ' ' + str(oldCpid) + s + istr, ha='left',
                    va='center', size=10)

    # Format the xaxis.
    xmin = date2num(times[0])
    xmax = date2num(times[len(times) - 1])
    xrng = (xmax - xmin)
    inter = int(round(xrng / 6. * 86400.))
    inter2 = int(round(xrng / 24. * 86400.))
    ax.xaxis.set_minor_locator(SecondLocator(interval=inter2))
    ax.xaxis.set_major_locator(SecondLocator(interval=inter))

    for tick in ax.xaxis.get_major_ticks():
        tick.label.set_fontsize(0)

    # Identify the CPID axis with a label.
    fig = ax.get_figure()
    bb = ax.get_position()
    x0 = bb.x0
    y0 = bb.y0
    height = bb.height
    width = bb.width
    pos = [x0, y0, width, height]
    fig.text(pos[0] - .07, pos[1] + pos[3] / 2., 'CPID', ha='center',
             va='center', size=8.5, rotation='vertical')
    ax.set_yticks([])

def plot_skynoise(ax, times, sky, xlim=None, xticks=None):
    """Plots a noise panel at position pos.

    Parameters
    ----------
    ax :
        a MPL axis object to plot to
    times : list
        a list of the times of the beam soundings
    sky: list
        a lsit of the noise.sky of the beam soundings
    search : list
        a list of the noise.search param
    xlim : Optional[list]
        2-element limits of the x-axis.  None for default.
    xticks : Optional[list]
        List of xtick poisitions.  None for default.

    Returns
    -------
    Nothing

    Example
    -------
        plot_skynoise(ax,times,sky)

    Written by AJ 20121002
    Modified by NAF 20131101
    Modified by ASR 20150916

    """

    from matplotlib.ticker import MultipleLocator
    from matplotlib.dates import date2num
    from matplotlib.lines import Line2D
    import numpy as np

    # Format the yaxis.
    ax.yaxis.tick_left()
    ax.yaxis.set_tick_params(direction='out')
    ax.set_ylim(bottom=0, top=6)
    ax.yaxis.set_minor_locator(MultipleLocator())
    ax.yaxis.set_tick_params(direction='out', which='minor')

    # Plot the sky noise data.
#    if np.all(sky):
#        sky_log10 = np.log10(sky)
#    else:
#        sky_log10 = np.array([0]*len(sky))
#    #sky_log10 = [np.log10(x) if x>0 else np.nan for x in sky]
    sky_log10 = np.log10(sky)
    ax.plot_date(date2num(times), sky_log10, fmt='k-',
                 tz=None, xdate=True, ydate=False)

    # Format the xaxis.
    if xlim is not None: ax.set_xlim(xlim)
    if xticks is not None: ax.set_xticks(xticks)

    # Add labels to identify the noise axis.
    fig = ax.get_figure()
    bb = ax.get_position()
    x0 = bb.x0
    y0 = bb.y0
    height = bb.height
    width = bb.width
    pos = [x0, y0, width, height]
    fig.text(pos[0] - .01, pos[1] + .004, '10^0', ha='right', va='bottom',
             size=8)
    fig.text(pos[0] - .01, pos[1] + pos[3], '10^6', ha='right', va='top',
             size=8)
    fig.text(pos[0] - .07, pos[1] + pos[3] / 2., 'N.Sky', ha='center',
             va='center', size=8.5, rotation='vertical')
    l = Line2D([pos[0] - .06, pos[0] - .06], [pos[1] + .01,
               pos[1] + pos[3] - .01], transform=fig.transFigure,
               clip_on=False, ls='-', color='k', lw=1.5)
    ax.add_line(l)
    ax.set_xticklabels([' '])
    # Only use 2 major yticks.
    ax.set_yticks([0, 6])
    ax.set_yticklabels([' ', ' '])

def plot_searchnoise(ax, times, search, xlim=None, xticks=None,
                     ytickside='right'):
    """Plots a noise panel at position pos.

    Parameters
    ----------
    ax :
        a MPL axis object to plot to
    times : list
        a list of the times of the beam soundings
    sky : list
        a lsit of the noise.sky of the beam soundings
    search : list
        a list of the noise.search param
    xlim : Optional[list]
        2-element limits of the x-axis.  None for default.
    xticks : Optional[list]
        List of xtick poisitions.  None for default.
    ytickside : Optional[string]
        Default is right.

    Returns
    -------
    Nothing

    Example
    -------
        plot_searchnoise(ax,times,search)

    Written by AJ 20121002
    Modified by NAF 20131101
    Modified by ASR 20150916

    """

    from matplotlib.ticker import MultipleLocator
    from matplotlib.dates import date2num
    from matplotlib.lines import Line2D
    import numpy as np

    # Format the yaxis.
    ax.yaxis.tick_left()
    ax.yaxis.set_tick_params(direction='out')
    ax.set_ylim(bottom=0, top=6)
    ax.yaxis.set_minor_locator(MultipleLocator())
    ax.yaxis.set_tick_params(direction='out', which='minor')

    # Plot the search noise data.
#    if np.all(search):
#        search_log10 = np.log10(search)
#    else:
#        search_log10 = np.array([0]*len(search))
#    search_log10 = [np.log10(x) if x>0 else np.nan for x in search]
    search_log10 = np.log10(search)
    ax.plot_date(date2num(times), search_log10,
                 fmt='k:', tz=None, xdate=True, ydate=False, lw=1.5)

    # Format the xaxis.
    if xlim is not None: ax.set_xlim(xlim)
    if xticks is not None: ax.set_xticks(xticks)

    # Add labels to identify the noise axis.
    fig = ax.get_figure()
    bb = ax.get_position()
    x0 = bb.x0
    y0 = bb.y0
    height = bb.height
    width = bb.width
    pos = [x0, y0, width, height]

    fig.text(pos[0] + pos[2] + .01, pos[1] + .004, '10^0', ha='left',
             va='bottom', size=8)
    fig.text(pos[0] + pos[2] + .01, pos[1] + pos[3], '10^6', ha='left',
             va='top', size=8)
    fig.text(pos[0] + pos[2] + .06, pos[1] + pos[3] / 2., 'N.Sch', ha='center',
             va='center', size=8.5, rotation='vertical')

    l = Line2D([pos[0] + pos[2] + .07, pos[0] + pos[2] + .07],
                     [pos[1] + .01, pos[1] + pos[3] - .01],
                     transform=fig.transFigure, clip_on=False, ls=':',
                     color='k', lw=1.5)
    ax.add_line(l)
    ax.set_xticklabels([' '])
    # use only 2 major yticks
    ax.set_yticks([0, 6])
    ax.set_yticklabels([' ', ' '])
    if ytickside == 'right':
        ax.yaxis.tick_right()

def plot_freq(ax, times, freq, xlim=None, xticks=None):
    """Plots the tx frequency data to an axis object.

    Parameters
    ----------
    ax :
        a MPL axis object to plot to
    times : list
        a list of the times of the beam soundings
    freq : list
        a lsit of the tfreq of the beam soundings
    xlim : Optional[list]
        2-element limits of the x-axis.  None for default.
    xticks : Optional[list]
        List of xtick poisitions.  None for default.

    Returns
    -------
    Nothing.

    Example
    -------
        plot_freq(ax, times, tfreq)

    Written by AJ 20121002
    Modified by NAF 20131101
    Modified by ASR 20150916

    """

    from matplotlib.ticker import MultipleLocator
    from matplotlib.dates import date2num
    from matplotlib.lines import Line2D

    # Format the yaxis.
    ax.yaxis.tick_left()
    ax.yaxis.set_tick_params(direction='out')
    ax.set_ylim(bottom=8, top=20)
    ax.yaxis.set_minor_locator(MultipleLocator())
    ax.yaxis.set_tick_params(direction='out', which='minor')

    # Plot the TX frequency.
    ax.plot_date(date2num(times), freq, fmt='k-',
                 tz=None, xdate=True, ydate=False, markersize=2)

    # Format the xaxis.
    if xlim is not None: ax.set_xlim(xlim)
    if xticks is not None: ax.set_xticks(xticks)

    # Add labels to identify the frequency axis.
    fig = ax.get_figure()
    bb = ax.get_position()
    x0 = bb.x0
    y0 = bb.y0
    height = bb.height
    width = bb.width
    pos = [x0, y0, width, height]
    fig.text(pos[0] - .01, pos[1] + .005, '10', ha='right', va='bottom',
             size=8)
    fig.text(pos[0] - .01, pos[1] + pos[3] - .015, '16', ha='right', va='top',
             size=8)
    fig.text(pos[0] - .07, pos[1] + pos[3] / 2., 'Freq', ha='center',
             va='center', size=9, rotation='vertical')
    fig.text(pos[0] - .05, pos[1] + pos[3] / 2., '[MHz]', ha='center',
             va='center', size=7, rotation='vertical')
    l = Line2D([pos[0] - .04, pos[0] - .04], [pos[1] + .01,
               pos[1] + pos[3] - .01], transform=fig.transFigure,
               clip_on=False, ls='-', color='k', lw=1.5)
    ax.add_line(l)
    ax.set_xticklabels([' '])
    # use only 2 major yticks
    ax.set_yticks([10, 16])
    ax.set_yticklabels([' ', ' '])

def plot_nave(ax, times, nave, xlim=None, xticks=None, ytickside='right'):
    """Plots the number of averages (nave) data to an axis object.

    Parameters
    ----------
    ax :
        a MPL axis object to plot to
    times : list
        a list of the times of the beam soundings
    nave : list
        a lsit of the nave of the beam soundings
    xlim : Optional[list]
        2-element limits of the x-axis.  None for default.
    xticks : Optional[list]
        List of xtick poisitions.  None for default.
    ytickside : Optional[str]
        Default is right.

    Returns
    -------
    Nothing.

    Example
    -------
        plot_nave(ax, times, nave)

    Written by AJ 20121002
    Modified by NAF 20131101
    Modified by ASR 20150916

    """

    from matplotlib.ticker import MultipleLocator
    from matplotlib.dates import date2num
    from matplotlib.lines import Line2D

    # Format the yaxis
    ax.yaxis.tick_left()
    ax.yaxis.set_tick_params(direction='out')
    ax.set_ylim(bottom=0, top=80)
    ax.yaxis.set_minor_locator(MultipleLocator(base=5))
    ax.yaxis.set_tick_params(direction='out', which='minor')

    # Plot the number of averages.
    ax.plot_date(date2num(times), nave, fmt='k:',
                 tz=None, xdate=True, ydate=False, markersize=2)

    # Format the xaxis.
    if xlim is not None: ax.set_xlim(xlim)
    if xticks is not None: ax.set_xticks(xticks)

    # Add labels to identify the nave axis.
    fig = ax.get_figure()
    bb = ax.get_position()
    x0 = bb.x0
    y0 = bb.y0
    height = bb.height
    width = bb.width
    pos = [x0, y0, width, height]
    fig.text(pos[0] + pos[2] + .01, pos[1] - .004, '0', ha='left', va='bottom',
             size=8)
    fig.text(pos[0] + pos[2] + .01, pos[1] + pos[3], '80', ha='left', va='top',
             size=8)
    fig.text(pos[0] + pos[2] + .06, pos[1] + pos[3] / 2., 'Nave', ha='center',
             va='center', size=8.5, rotation='vertical')

    l = Line2D([pos[0] + pos[2] + .07, pos[0] + pos[2] + .07],
               [pos[1] + .01, pos[1] + pos[3] - .01],
               transform=fig.transFigure, clip_on=False, ls=':',
               color='k', lw=1.5)
    ax.add_line(l)
    ax.set_xticklabels([' '])
    # use only 2 major yticks
    ax.set_yticks([0, 80])
    ax.set_yticklabels([' ', ' '])
    if ytickside == 'right':
        ax.yaxis.tick_right()

def read_data(myPtr, bmnum, params, tbands):
    """Reads data from the file pointed to by myPtr

    Parameter
    ---------
    myPtr :
        a davitpy file pointer object
    bmnum : int
        beam number of data to read in
    params : list
        a list of the parameters to read
    tbands : list
        a list of the frequency bands to separate data into

    Returns
    -------
    A dictionary of the data. Data is stored in lists and separated in
    to tbands.

    Example
    -------
        from davitpy import pydarn
        from datetime import datetime
        myPtr = pydarn.sdio.radDataOpen(datetime(2012,11,24),'sas')
        myBeam = myPtr.readRec()
        data_dict = read_data(myPtr, myBeam, 7, ['velocity'], [8000,20000])

    Written by ASR 20150914

    """

    import numpy as np

    # Initialize some things.
    data = dict()
    data_keys = ['vel', 'pow', 'wid', 'elev', 'phi0', 'datetime', 'freq', 'cpid',
                 'nave', 'nsky', 'nsch', 'slist', 'mode', 'rsep', 'nrang',
                 'frang', 'gsflg', 'velocity_error']
    for d in data_keys:
        data[d] = []

    # Read the parameters of interest.
    myPtr.rewind()
    myBeam = myPtr.readRec()
    while(myBeam is not None):
        if(myBeam.time > myPtr.eTime): break
        if(myBeam.bmnum == bmnum and (myPtr.sTime <= myBeam.time)):
            if (myBeam.prm.tfreq >= tbands[0] and
                myBeam.prm.tfreq <= tbands[1]):
                data['datetime'].append(myBeam.time)
                data['cpid'].append(myBeam.cp)
                data['nave'].append(myBeam.prm.nave)
                data['nsky'].append(myBeam.prm.noisesky)
                data['rsep'].append(myBeam.prm.rsep)
                data['nrang'].append(myBeam.prm.nrang)
                data['frang'].append(myBeam.prm.frang)
                data['nsch'].append(myBeam.prm.noisesearch)
                data['freq'].append(myBeam.prm.tfreq / 1e3)
                data['slist'].append(myBeam.fit.slist)
                data['mode'].append(myBeam.prm.ifmode)
                data['gsflg'].append(myBeam.fit.gflg)
                # To save time and RAM, only keep the data specified
                # in params.
                if('velocity' in params):
                    data['vel'].append(myBeam.fit.v)
                if('power' in params):
                    data['pow'].append(myBeam.fit.p_l)
                if('width' in params):
                    data['wid'].append(myBeam.fit.w_l)
                if('elevation' in params):
                    data['elev'].append(myBeam.fit.elv)
                if('phi0' in params):
                    data['phi0'].append(myBeam.fit.phi0)
                if('velocity_error' in params):
                    data['velocity_error'].append(myBeam.fit.v_e)

        myBeam = myPtr.readRec()
    return data

def rti_panel(ax, data_dict, pArr, gsct, rad, bmnum, coords, cmap,
              norm, plot_terminator=True):
    """Plots the data given by pArr to an axis object.

    Parameters
    ----------
    ax :
        a MPL axis object to plot to
    data_dict :
        the data dictionary returned by pydarn.plotting.read_data
    pArr : list
        the list of data to be plotted (e.g. data_dict['vel'] for
        velocity)
    gsct : bool
        a boolean stating whether to flag ground scatter data or not
    rad : str
        the 3 letter radar code
    bmnum : int
        The beam number of the data to plot
    coords : str
        plotting coordinates ('gate', 'range', 'geo', 'mag')
    cmap :
        a matplotlib.colors.ListedColormap (such as that returned
        by utils.plotUtils.genCmap)
    norm :
        a matplotlib.colors.BoundaryNorm (such as that returned by
        utils.plotUtils.genCmap)
    plot_terminator : Optional[bool]
        A boolean stating whether or not to plot the terminator; default
        is true.

    Returns
    -------
    pcoll
        the polygon collection returned by matplotib.pyplot.pcolormesh.

    Written by ASR 20150916

    """
    from davitpy import pydarn
    import matplotlib
    from matplotlib.dates import date2num, num2date
    import numpy as np

    # Initialize things.
    rmax = max(data_dict['nrang'])
    tmax = (len(data_dict['datetime'])) * 2
    data = np.zeros((tmax, rmax)) * np.nan
    x = np.zeros(tmax)
    tcnt = 0

    # Build a list of datetimes to plot each data point at.
    dt_list = []
    for i in range(len(data_dict['datetime'])):
        x[tcnt] = date2num(data_dict['datetime'][i])
        dt_list.append(data_dict['datetime'][i])

        if(i < len(data_dict['datetime']) - 1):
            if(date2num(data_dict['datetime'][i + 1]) - x[tcnt] > 4. / 1440.):
                tcnt += 1
                # 1440 minutes in a day, hardcoded 1 minute step per data point
                # but only if time between data points is > 4 minutes
                x[tcnt] = x[tcnt - 1] + 1. / 1440.
                dt_list.append(num2date(x[tcnt]))
        tcnt += 1

        if(pArr[i] == [] or pArr[i] is None): continue

        if data_dict['slist'][i] is not None:
            for j in range(len(data_dict['slist'][i])):
                if(not gsct or data_dict['gsflg'][i][j] == 0):
                    data[tcnt][data_dict['slist'][i][j]] = pArr[i][j]
                elif gsct and data_dict['gsflg'][i][j] == 1:
                    data[tcnt][data_dict['slist'][i][j]] = -100000.

    # For geo or mag coords, get radar FOV lats/lons.
    if (coords != 'gate' and coords != 'rng') or plot_terminator is True:
        site = pydarn.radar.network().getRadarByCode(rad) \
            .getSiteByDate(data_dict['datetime'][0])
        myFov = pydarn.radar.radFov.fov(site=site, ngates=rmax,
                                        nbeams=site.maxbeam,
                                        rsep=data_dict['rsep'][0],
                                        coords=coords,
                                        date_time=data_dict['datetime'][0])
        myLat = myFov.latCenter[bmnum]
        myLon = myFov.lonCenter[bmnum]

    # Determine the yaxis range limits to plot data to.
    if(coords == 'gate'):
        y = np.linspace(0, rmax, rmax + 1)
    elif(coords == 'rng'):
        y = np.linspace(data_dict['frang'][0],
                           rmax * data_dict['rsep'][0],
                           rmax + 1)
    else:
        y = myFov.latFull[bmnum]

    # Generate a mesh of x and y coords to plot data to.
    X, Y = np.meshgrid(x[:tcnt], y)

    # Calculate terminator as required.
    if plot_terminator:
        daylight = np.ones([len(dt_list), len(myLat)], np.bool)
        for tm_inx in range(len(dt_list)):
            tm = dt_list[tm_inx]
            term_lats, tau, dec = daynight_terminator(tm, myLon)
            if dec > 0:
                # NH Summer
                day_inx = np.where(myLat < term_lats)[0]
            else:
                day_inx = np.where(myLat > term_lats)[0]

            if day_inx.size != 0:
                daylight[tm_inx, day_inx] = False
        daylight = np.ma.array(daylight, mask=daylight)
        ax.pcolormesh(X, Y, daylight.T, lw=0, alpha=0.10,
                      cmap=matplotlib.cm.binary_r, zorder=99)

    # Mask the nan's in the data array so they aren't plotted.
    Zm = np.ma.masked_where(np.isnan(data[:tcnt][:].T), data[:tcnt][:].T)
    # Set colormap so that masked data (bad) is transparent.
    cmap.set_bad('w', alpha=0.0)

    # Now let's plot all data.
    pcoll = ax.pcolormesh(X, Y, Zm, lw=0.01, edgecolors='None',
                          cmap=cmap, norm=norm)

    return pcoll

def daynight_terminator(date, lons):
    """ Return the coordinates of day/night terminator for RTI plotting.

    Parameters
    ----------
    date : datetime.datetime
        a datetime.datetime object (assumed UTC)
    lons : list
        a numpy array of lons

    Returns
    -------
    lat
        the latitude of the day night terminator
    tau
        grenwich hour angle
    dec
        solar declination

    """
    import mpl_toolkits.basemap.solar as solar
    import numpy as np

    dg2rad = np.pi / 180.
    # compute greenwich hour angle and solar declination
    # from datetime object (assumed UTC).
    tau, dec = solar.epem(date)
    # compute day/night terminator from hour angle, declination.
    longitude = lons + tau
    lats = np.arctan(-np.cos(longitude * dg2rad) /
                     np.tan(dec * dg2rad)) / dg2rad
    return lats, tau, dec


'''
How to play

Welcome to Blackjack! This guide shall walk you through the basics of the game and get you ready to hit the tables with confidence.

Objective
The main objective is to obtain a hand with a total value higher than the dealer's without going over 21.

Players
The game involves at least two players, the Dealer and Player. In this Blackjack game you, Player, will play against the dealer.

The game uses the standard 52-card deck. Each player will be handed two cards each; yours will be face-up but only one of the Dealer's will be shown. Each turn after, you will be given the option to keep the cards (stay) or get more (draw) depending on their current total. Remember, don't go over 21!

*Hint: The Dealer is programmed to keep drawing as long as their current value is not yet over 16.

If your total hits exactly 21, congratulations that's a blackjack!

Step 2: Card Values

Before you dive into the action, familiarize yourself with the card values:

Number cards (2-10): Face value
Face cards (Jack, Queen, King): 10 points each
Ace: 1 or 11 points (whichever benefits you more)
Step 3: The Deal

You receive two cards, both face-up. The dealer also gets two cards, but one is face-down (the hole card). This adds an element of mystery and strategy to the game.

Step 4: Aim for 21, but Don't Go Over!

Your goal is to get a hand value as close to 21 as possible without exceeding it. If you go over 21, you bust and lose the round. But if you hit 21 exactly with your first two cards, congratulations – you've got a blackjack and win extra!
'''

import random

class BlackjackGame:
    def __init__(self):
        self.deck = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] * 4
        self.player_hand = set()
        self.dealer_hand = set()

    def deal_card(self, hand):
        card = random.choice(self.deck)
        hand.add(card)
        self.deck.remove(card)

    def display_hands(self, show_all=False):
        print("Player's hand:", self.player_hand)

        if show_all:
            print("Dealer's hand:", self.dealer_hand)
        else:
            print("Dealer's hand: {hidden card}")

# Example usage:
game = BlackjackGame()

# Deal initial cards
game.deal_card(game.player_hand)
game.deal_card(game.dealer_hand)
game.deal_card(game.player_hand)
game.deal_card(game.dealer_hand)

# Display hands with hidden card
game.display_hands(show_all=False)


from milk.supervised.normalise import normaliselabels
import numpy as np

def test_normaliselabels():
    np.random.seed(22)
    labels = np.zeros(120, np.uint8)
    labels[40:] += 1
    labels[65:] += 1
    reorder = np.argsort(np.random.rand(len(labels)))
    labels = labels[reorder]
    labels2,names = normaliselabels(labels)
    for new_n,old_n in enumerate(names):
        assert np.all( (labels == old_n) == (labels2 == new_n) )

def test_normaliselabels_multi():
    np.random.seed(30)
    r = np.random.random
    for v in range(10):
        labels = []
        p = np.array([.24,.5,.1,.44])
        for i in range(100):
            cur = [j for j in range(4) if r() < p[j]]
            if not cur: cur = [0]
            labels.append(cur)
        nlabels, names = normaliselabels(labels, True)
        assert len(labels) == len(nlabels)
        assert len(nlabels[0]) == max(list(map(max,labels)))+1
        assert nlabels.sum() == sum(map(len,labels))


import math

triangle = 1
number = 2

found = False
while not found:
    triangle += number
    number += 1

    count = 2
    for divisor in range(2, math.floor(math.sqrt(triangle))):
        if triangle % divisor == 0:
            count += 2  # because of mirror factors!

    print(f'{triangle:<12} {count:<5}')
    if count >= 500:
        found = True
        print(triangle)


"""short.py

Functions for short selling investors
"""
from decimal import Decimal
from entities import Portfolio
import logging
import random

# Set logging configuration
logging.basicConfig(level=logging.DEBUG,
                    format=' %(asctime)s - %(levelname)s - %(message)s')
# logging.disable(logging.CRITICAL)

def short_seller(investor, broker):

    old_portfolio = investor.portfolios[0]
    new_portfolio = investor.portfolios[1]
    # logging.info("new_portfolio: %s" % new_portfolio)
    # logging.info(new_portfolio.portfolios[0][2])
    stock_price = Decimal(str(old_portfolio.portfolios[0][2]))
    cur_stk_price = Decimal(str(new_portfolio.portfolios[0][2]))
    stock_quant = old_portfolio.portfolios[0][1]
    stock_symbol = old_portfolio.portfolios[0][0]

    # logging.info(old_portfolio.value)
    # looking for decres in stock price

    # If true we buy back the stock at a lose
    max_loss = (0.5*((investor.cash)+float(old_portfolio.value)) - (investor.risk_money))
    logging.info("short seller: %s" % investor)

    if stock_price == cur_stk_price:
        logging.info("stock_price %s is equal to cur_stk_price %s" % (stock_price, cur_stk_price))
        return "stock_price is equal to cur_stk_price"

    elif (stock_price-cur_stk_price > 0):
        investor.portfolios[0].remove_stock(stock_symbol, stock_quant)
        del investor.portfolios[0]
        investor.cash += float(old_portfolio.value)
        # buy new portfolio
        investor.portfolios[0].add_stock(stock_symbol, stock_quant, cur_stk_price)
        investor.cash -= float(new_portfolio.value)
        #investor.portfolios[0].remove_stock(stock_symbol)
        #investor.cash = investor.cash + stock_total_value
        #investor.portfolios[0].add_stock(stock_symbol,stock_quant,cur_stk_price)
        #investor.cash = investor.cash - (cur_stk_price*stock_quant)
        logging.info("stock bought back at a profit %s ... %s " % (stock_price, cur_stk_price))
    elif ((stock_quant * cur_stk_price) >= max_loss):
        # sale old portfolio, get cash
        investor.portfolios[0].remove_stock(stock_symbol, stock_quant)
        del investor.portfolios[0]
        investor.cash += float(old_portfolio.value)
        # buy new portfolio
        investor.portfolios[0].add_stock(stock_symbol, stock_quant, cur_stk_price)
        investor.cash -= float(new_portfolio.value)
        logging.info("bought back at a lose %s .. %s" % (stock_price, cur_stk_price))

    else:
        logging.info("short selling didn't buy back stocks")

    #print "\n","trade.py",stock_symbol,invest_portf.portfolios, stock_total_value
    #print "\n","current price of ",stock_symbol,cur_stk_price


import os, re, json
from os.path import exists
from math import log2
import time
from collections import OrderedDict

WORD_FILE = "corpus.txt"
FIRST_GUESS_FILE = "first_guess.json"
#NUM_GOOD_GUESSES = 50
NUM_GOOD_GUESSES = 2315
HARD_MODE = False
MIN_EASY_MODE_POSSIBLE_ANSWER_SIZE = 0 # normally 3 but setting to 0 disables the feature

def create_list():
	regex = re.compile('[^a-zA-Z]')
	result = []
	with open(WORD_FILE,'r') as file:
		for line in file:
			for word in line.split():
				# to lower case
				word = word.lower()
				# strip non-alpha char's
				#First parameter is the replacement, second parameter is your input string
				word = regex.sub('', word)
				# skip non-5 letter words (the file has some 'and's in it)
				if len(word)==5:
					result.append(word)
	return set(result) # eliminate duplicates

def get_hint(guess, target):
	return hint_value_from_string(get_hint_as_string(guess, target))

# return the number of time 'character' occurs in 'target_string'
def char_count(target_string, character):
	return sum(map(lambda x : 1 if character in x else 0, target_string))

# If a guess has multiple copies of a letter but the answer has just
# one copy, then only one of the letters will be illuminated.
def get_hint_as_string(guess, target):
	#TODO raise exception if guess and target are not 5 letters
	result = ['-','-','-','-','-']
	unique_chars_in_guess = set([char for char in guess])
	for guess_char in unique_chars_in_guess:
		exact_match_ctr = 0
		for i in range(0, len(guess)):
			if guess[i]==guess_char and target[i]==guess_char:
				result[i]='g'
				exact_match_ctr = exact_match_ctr + 1
		# count the number of time guess_char is in **target** and subtract 'exact_match_ctr'
		remaining_char_count = char_count(target, guess_char) - exact_match_ctr
		# go through and tag as 'y' up to remaining_char_count instances of guess_char
		# where they don't exactly match target
		imperfect_match_ctr = 0
		for i in range(0, len(guess)):
			if imperfect_match_ctr >= remaining_char_count:
				break
			if guess[i]==guess_char and target[i]!=guess_char:
				# so 'guess_char' is at pos'n i in guess, it's not an exact
				# match, but since we did not 'break' (above), there is *some*
				# unlabeled place in target where 'guess_char' occurs

				result[i]='y'
				imperfect_match_ctr = imperfect_match_ctr + 1

	return "".join(result)

# '--yg-' -> 1*9+2*3 = 15
def hint_value_from_string(s):
	multiplier = 3
	result = 0
	for i in range(0,len(s)):
		result = result * 3
		if s[i]=='g':
			result = result + 2 # green
		elif s[i]=='y':
			result = result + 1 # yellow
		elif s[i]!='-':
			raise Exception("Hint must contain only '-', 'y', 'g'")
		# else grey
	return result

# A guess partitions a set of possible targets according to the hint
# that Wordle returns
def partition(guess, possible_answers):
	partition = {}
	for target in possible_answers:
		hint = get_hint(guess, target) # returns a number 1->243
		hint_set = partition.get(hint, [])
		hint_set.append(target)
		partition[hint]=hint_set
	return partition

# given a list of guesses and a target, return the hints as one long string
def get_hints_as_string(guesses, target):
	result = ""
	for guess in guesses:
		hint = get_hint_as_string(guess, target)
		result = result+hint
	return result

def partition_from_multiple_guesses(guesses, possible_answers):
	partition = {}
	for target in possible_answers:
		hint = hint_value_from_string(get_hints_as_string(guesses, target))
		hint_set = partition.get(hint, [])
		hint_set.append(target)
		partition[hint]=hint_set
	return partition

#
# Original rank is the average size of the resultant list after
# the hint is returned
#
# This video (https://www.youtube.com/watch?v=v68zYyaEmEA) suggests
# maximizing information/entropy which means minimizing the expected
# log(partition size)
#
#
#
def rank_partition(partition):
	result = 0
	total = 0
	for value in partition.values():
		n = len(value)
		total = total + n
	for value in partition.values():
		n = len(value)
		# original:
		result = result + n*n
		# information theoretic:
		# result = result + n*log2(n/total)
	return result/total

# returns a list of guesses, ordered by their rank
# result is a list of dict's with keys, 'rank', 'guess', 'partition'
def optimize_guess(possible_guesses, possible_answers):
	# If the number of possible answers is small, don't use 'easy mode', in which a guess
	# can be outside the list of possible answers.  Just use 'hard mode', i.e., only guess
	# one of the possible answers
	if len(possible_guesses) > len(possible_answers) and len(possible_answers)<MIN_EASY_MODE_POSSIBLE_ANSWER_SIZE:
		possible_guesses = possible_answers
	result = [] # a list of dict's with keys, 'rank', 'guess', 'partition'
	for guess in possible_guesses:
		partition_for_guess = partition(guess, possible_answers)
		guess_rank = rank_partition(partition_for_guess)
		guess_entry = {'rank':guess_rank, 'guess':guess, 'partition':partition_for_guess}
		#print(f"Guess {guess} has rank {guess_rank}")
		inserted=False
		for i in range(0, len(result)):
			if guess_rank < result[i]['rank'] or (guess_rank == result[i]['rank'] and guess in possible_answers):
				result.insert(i,guess_entry)
				inserted=True
				result = result[0:NUM_GOOD_GUESSES]
				break
		if not inserted and len(result)<NUM_GOOD_GUESSES:
			result.append(guess_entry)

	return result

def rank_all_words(words, initial_guesses):
	stats = {}
	target_counter = 0
	for target in words:
		guesses = []
		possible_answers = words
		guess_counter = 0
		while guess_counter < 100:
			if guess_counter==0:
				best_guesses = initial_guesses
			else:
				if HARD_MODE:
					best_guesses = optimize_guess(possible_answers, possible_answers)
				else:
					best_guesses = optimize_guess(words, possible_answers)
			best_guess = best_guesses[0] # just pick the top guess
			wordle_hint = get_hint(best_guess['guess'], target)
			best_partition = best_guess['partition']
			possible_answers = best_partition[wordle_hint]
			guess_counter = guess_counter + 1
			guesses.append(best_guess['guess'])
			if best_guess['guess']==target:
				break
		target_counter = target_counter + 1
		if target_counter % 100 == 0:
			print(f"target_counter {target_counter}")
		stats[guess_counter] = stats.get(guess_counter,0)+1
		#print(f"Target word {target} is guessed in {guess_counter} guesses: {guesses}.")
	print(stats)

def best_second_guess(words, initial_guesses):
	best_initial_guess = initial_guesses[0]
	print(f"Best initial guess is {best_initial_guess['guess']}")

	result = [] # list of dict's with keys, 'guess' and 'rank'

	for candidate_second_guess in words:
		# best_initial_guess["partition"] is a dict
		# mapping 'hints' to the set of words that will generate that hint
		weighted_second_guess_rank = 0
		count = 0
		for hint in best_initial_guess["partition"]:
			possible_answers = best_initial_guess["partition"][hint]

			# how does candidate_second_guess partition possible_answers?
			partition_for_guess = partition(candidate_second_guess, possible_answers)
			guess_rank = rank_partition(partition_for_guess)

			weighted_second_guess_rank = weighted_second_guess_rank + guess_rank*len(possible_answers)
			count = count + len(possible_answers)

		rank = weighted_second_guess_rank / count
		result.append({'guess':candidate_second_guess, 'rank':rank})
		print(f'Second guess {candidate_second_guess} has rank {rank}.')

	result.sort(key=lambda item:item.get('rank'))

	print("Second guesses:")
	for i in range(0,50):
		print(f"Second guess: {result[i]['guess']}, rank: {result[i]['rank']}")

	#print(result)

def best_multi_guess(word_set):
	best_rank = None

	words = list(word_set)
	for i in range(0, len(words)):
		print(f'{i} of {len(words)} [{words[i]}, ----]')
		for j in range(i+1,len(words)):
			guesses = [words[i], words[j]]
			partition = partition_from_multiple_guesses(guesses, words)
			rank = rank_partition(partition)
			if best_rank is None or rank<best_rank:
				best_rank=rank
				best_guesses = guesses
				print(f'Best guesses: {best_guesses}, rank={best_rank}')

def best_third_guess(word_set):
	best_rank = None

	words = list(word_set)
	for i in range(0, len(words)):
		guesses = ['salon', 'trice', words[i]]
		partition = partition_from_multiple_guesses(guesses, words)
		rank = rank_partition(partition)
		if best_rank is None or rank<best_rank:
			best_rank=rank
			best_guesses = guesses
			print(f'Best guesses: {best_guesses}, rank={best_rank}')

def rank_select_word_pairs(word_set):
	words = list(word_set)
	rank_select_word_pair(['salon', 'trice'], words)
	rank_select_word_pair(['raise', 'clout'], words)
	rank_select_word_pair(['learn', 'pouty'], words)

def rank_select_word_pair(pair, words):
	partition = partition_from_multiple_guesses(pair, words)
	rank = rank_partition(partition)
	print(f'rank for {pair} is {rank}.')

def read_initial_guess_file():
	with open(FIRST_GUESS_FILE) as infile:
		initial_guesses = json.load(infile)
		# The JSON package turns our int keys into strings, so we have to fix them
		for initial_guess in initial_guesses:
			best_partition = {}
			for key in initial_guess["partition"].keys():
				best_partition[int(key)] = initial_guess["partition"][key]
			initial_guess["partition"] = best_partition
	return initial_guesses

def main():
	if HARD_MODE:
		print("Using HARD mode.")
	else:
		print("Using EASY mode.")
	words = create_list()
	if not exists(FIRST_GUESS_FILE):
		start = time.perf_counter()
		best_guesses = optimize_guess(words, words)
		print(f"{time.perf_counter()-start} seconds to rank initial guesses")
		with open(FIRST_GUESS_FILE, "w") as outfile:
			json.dump(best_guesses, outfile)
	initial_guesses = read_initial_guess_file()

	if False: # rank all words
		rank_all_words(words, initial_guesses)
		return 0

	if False:
		best_second_guess(words, initial_guesses)
		return 0

	if False:
		best_multi_guess(words)
		return 0

	if False:
		best_third_guess(words)
		return 0

	if False:
		rank_select_word_pairs(words)
		return 0

	# interactive application
	possible_answers = words
	for i in range(0,5):
		print(f"There are {len(possible_answers)} possible answers.")
		if len(possible_answers)<100:
			print(f"\t{possible_answers}")
		# get result of user placing guess
		if i==0:
			best_guesses = initial_guesses
		else:
			if HARD_MODE:
				best_guesses = optimize_guess(possible_answers, possible_answers) # <<< ONLY guess a possible answer
			else:
				best_guesses = optimize_guess(words, possible_answers) # <<< ANY word can be a guess

		print(f"\nTop guesses: ", end='')
		for guess in best_guesses:
			if guess['guess'] in possible_answers:
				print(f"{guess['guess'].upper()} ({guess['rank']:.1f})", end=' ')
			else:
				print(f"{guess['guess']} ({guess['rank']:.1f})", end=' ')

		print('')
		chosen_guess = input("Enter your guess: ")
		best_partition = None
		for guess in best_guesses:
			if guess['guess']==chosen_guess:
				best_partition = guess["partition"]
		if best_partition is None:
			raise Exception("You must choose one of the suggested guesses.")

		wordle_response = input("Enter wordle's response (5 chars of 'g', 'y', or '-'): ")
		if len(wordle_response)!=5:
			raise Exception("Hint (Wordle response) must have length five.")
		wordle_hint = hint_value_from_string(wordle_response)
		try:
			possible_answers = best_partition[wordle_hint]
		except Exception as e:
			print(best_partition)
			raise(e)
		if len(possible_answers)<2:
			break
	if len(possible_answers)==1:
		print(f"The answer is: {possible_answers[0]}.")
	else:
		print(f"Possible answers: {possible_answers}.")

if __name__ == "__main__":
    main()


i, k, guguline = 0, 0, ""

for i in range(2,10):
  guguline += ("#   %d단  #" %i)
print(guguline)

for i in range(1,10):
  guguline = ""
  for k in range(2,10):
    guguline += str("%2dX %2d= %2d" %(k,i,i*k))
  print(guguline)

#다시 확인
#문자열 계속 이어서 변수 저장 가능


"""
Read in h5 files containing inputs of MCMAC and output a table for paper
"""

from __future__ import division
import sys
import os
import h5py
sys.path.append(os.path.abspath("../multiDim_plot"))
from plotmod import round_to_n_sig_fig
from astropy.stats import biweight_midvariance as S_BI
from astropy.stats import biweight_location as C_BI

# import homebrewed module
import pandas as pd

if len(sys.argv) < 2:
    sys.exit("ERROR " +
             "you have to specify which hdf5 file you want as argument")
else:
    h5_file = sys.argv[1]

f = h5py.File(h5_file, "r")
m_main = f["m_main"][...] / (1e14)
m_sub = f["m_sub"][...] / (1e14)
z_main = f["z_main"][...]
z_sub = f["z_sub"][...]
d_proj = f["D_proj"][...]
f.close()

dat = pd.read_table("../call_MCMAC/el_gordo_chain.txt", sep="\s*", skiprows=3)
c_main = dat["cNW"]
c_sub = dat["cSE"]
# convert the mass into concentration
# estimate the mean and 1 sigma confidence level of the inputs

# we want to be able to output these filling the gaps to a file
# this would be incorporated as part of ElGordo1.tex
paper1 = "/Users/karenyng/Documents/Research/papers/ElGo_paper/texFiles/"
F = open(paper1 + "input_table.tex", "w")
F.write("\setcounter{table}{0}\n")
F.write("\\begin{table}\n")
F.write(
    "\caption{Properties of the sampling PDFs of the Monte Carlo " +
    "simulation} \n")
F.write("\\begin{center} \n")
F.write("\\begin{tabular}{@{}lcccc}\n")
F.write("\hline \hline Data & Units & Location & Scale & Ref\\\\ \hline\n")
F.write(
    "$M_{200c_{\mathrm{NW}}}$ & $10^{14} h_{70}^{-1}$ M$_{\odot}$" +
    " &{0:.1f}&{1:.1f}& \citetalias{{Jee13}}\\\\ \n".format(
        round_to_n_sig_fig(C_BI(m_main), 2), round(S_BI(m_main), 2)))
F.write("c$_{{\mathrm{{NW}}}}$ &  & {0:.2f}& {1:.2f}& ".format(
    round_to_n_sig_fig(C_BI(c_main), 2), round(S_BI(c_main), 2)) +
    "\citetalias{{Jee13}} \\\\ \n")
F.write("$M_{200c_{\mathrm{SE}}}$ & $10^{14} h_{70}^{-1}$ M$_{\odot}$" +
        " &{0:.1f}&{1:.1f} & \citetalias{{Jee13}}\\\\ \n".format(
            round_to_n_sig_fig(C_BI(m_sub), 2), round(S_BI(m_sub), 2)))
F.write("$c_{{\mathrm{{SE}}}}$ &  & {0:.2f} & {1:.2f}& ".format(
    round_to_n_sig_fig(C_BI(c_sub), 2), round(S_BI(c_sub), 2)) +
        "\citetalias{Jee13}\\\\ \n")
F.write("$z_{{\mathrm{{NW}}}}$ &  & {0:.5f}".format(
        round_to_n_sig_fig(C_BI(z_main), 5)) +
        " & {0:.5f}& \citetalias{{M12}}, \citetalias{{Sifon13}}\\\\ \n".format(
        round_to_n_sig_fig(S_BI(z_main), 5)))
F.write("$z_{{\mathrm{{SE}}}}$ &  & {0:.5f} & ".format(C_BI(z_sub)) +
        "{0:.5f}& \citetalias{{M12}}, \citetalias{{Sifon13}}\\\\ \n".format(
        round_to_n_sig_fig(S_BI(z_sub), 5)))
F.write("d$_{{\mathrm{{proj}}}}$ & Mpc & {0:.2g} &".format(
    round_to_n_sig_fig(C_BI(d_proj), 2)) +
        "{0:.2g} & \citetalias{{Jee13}} \\\\ \n".format(
            round_to_n_sig_fig(S_BI(d_proj), 2)))
F.write("\hline \n")
F.write("\end{tabular} \n")
F.write("\end{center} \n")
F.write("\label{tab:inputs} \n")
F.write("\end{table} \n")
F.close()


import torch
import torch.nn as nn

import gym
import env
import env.wrappers as wrappers
from capture import LiveMonitor

import driver
from gymviz import Plot

import buffer as bf
from algos import a2c
from torch.nn.functional import max_pool2d, log_softmax
from torch.distributions import Categorical
from config import exists_and_not_none, ArgumentParser
import wandb
import wandb_utils
import checkpoint
import baselines.helper as helper
import numpy as np
import os
import capture
import random
import models.atari as models

if __name__ == '__main__':

    """ configuration """
    parser = ArgumentParser(description='configuration switches')
    parser.add_argument('-c', '--config', type=str)
    parser.add_argument('-d', '--device', type=str, default='cuda')
    parser.add_argument('-r', '--run_id', type=int, default=-1)
    parser.add_argument('--comment', type=str)
    parser.add_argument('--silent', action='store_true', default=False)

    """ reproducibility """
    parser.add_argument('--seed', type=int, default=None)

    """ main loop control """
    parser.add_argument('--max_steps', type=int, default=1000000)
    parser.add_argument('--test_steps', type=int, default=5000)
    parser.add_argument('--test_episodes', type=int, default=25)
    parser.add_argument('--capture_freq', type=int, default=50000)

    """ resume settings """
    parser.add_argument('--demo', action='store_true', default=False)
    parser.add_argument('-l', '--load', type=str, default=None)

    """ environment """
    parser.add_argument('--env_name', type=str, default='BreakoutDeterministic-v4')
    parser.add_argument('--env_render', action='store_true', default=False)

    """ hyper-parameters """
    parser.add_argument('--optim_lr', type=float, default=1.3e-5)
    parser.add_argument('--batch_size', type=int, default=8)
    parser.add_argument('--discount', type=float, default=0.99)
    parser.add_argument('--hidden_dim', type=int, default=64)
    parser.add_argument('--exploration_noise', type=float, default=0.0565)

    config = parser.parse_args()

    """ check for device in environment variable """
    if 'DEVICE' in os.environ:
        config.device = os.environ['DEVICE']

    """ random seed """
    if config.seed is not None:
        torch.manual_seed(config.seed)
        #torch.backends.cudnn.benchmark = False
        #torch.use_deterministic_algorithms(True)

    wandb.init(project=f"a2c-{config.env_name}", config=config)

    """ environment """
    def make_env():
        env = gym.make(config.env_name)
        env = capture.VideoCapture(env, config.run_dir, freq=config.capture_freq)
        env = wrappers.EpisodicLifeEnv(env)
        if 'NOOP' in env.unwrapped.get_action_meanings():
            env = wrappers.NoopResetEnv(env)
        if 'FIRE' in env.unwrapped.get_action_meanings():
            env = wrappers.FireResetEnv(env)
        env = wrappers.ClipState2D(env, 0, 24, 210 - 24, 160)
        env = wrappers.WarpFrame(env)
        env = wrappers.ScaledFloatFrame(env)
        env = wrappers.Gradient(env)
        env = wrappers.ClipRewardEnv(env)
        env = wrappers.PenalizeOneIfDone(env)

        if config.seed is not None:
            env.seed(config.seed)
            env.action_space.seed(config.seed)
        return env

    """ training env with replay buffer """
    train_env, train_buffer = bf.wrap(make_env())
    train_env = wandb_utils.LogRewards(train_env)
    if not config.silent:
        train_env = Plot(train_env, episodes_per_point=20, title=f'Train a2c-{config.env_name}-{config.run_id}',
                         refresh_cooldown=5.0)

    """ test env """
    test_env = make_env()
    if not config.silent:
        test_env = Plot(test_env, episodes_per_point=config.test_episodes, title=f'Test a2c-{config.env_name}-{config.run_id}',
                        refresh_cooldown=5.0)
    evaluator = helper.Evaluator(test_env)

    actions = train_env.action_space.n

    """ network """
    a2c_net = models.A2CNet(
        hidden_dims=config.hidden_dim,
        actions=actions,
        exploration_noise=config.exploration_noise).to(config.device)
    optim = torch.optim.Adam(a2c_net.parameters(), lr=config.optim_lr, weight_decay=0.0)

    """ load weights from file if required"""
    if exists_and_not_none(config, 'load'):
        checkpoint.load(config.load, prefix='best', a2c_net=a2c_net, optim=optim)

    """ policy to run on environment """
    def policy(state):
        state = torch.from_numpy(state).float().unsqueeze(0).to(config.device)
        value, action = a2c_net(state)
        a = action.sample()
        assert torch.isnan(a) == False
        return a.cpu().numpy()

    """ demo  """
    evaluator.demo(config.demo, policy)

    """ main loop """
    steps = 0
    best_mean_return = -999999
    tests_run = 0

    for total_steps, _ in enumerate(driver.step_environment(train_env, policy)):
        steps += 1
        if total_steps > config.max_steps:
            break

        """ train online after batch steps saved"""
        if steps < config.batch_size:
            continue
        else:
            a2c.train(train_buffer, a2c_net, optim, discount=config.discount, batch_size=config.batch_size, device=config.device)
            steps = 0

        """ test  """
        if total_steps > config.test_steps * tests_run and total_steps != 0:
            tests_run += 1
            evaluator.evaluate(policy, config.run_dir, {'a2c_net': a2c_net, 'optim': optim},
                               sample_n=config.test_episodes, capture=True)


import moviepy.editor as mp
import matplotlib.pyplot as plt
import numpy as np
import wave
from pydub import AudioSegment

def mp32wav(file_in, file_out):
    sound = AudioSegment.from_mp3(file_in)
    sound.export(file_out, format="wav")

def split_audio(vid, out):
    my_clip = mp.VideoFileClip(vid)
    my_clip.audio.write_audiofile(out)

def audio2numpy(audio):
    raw = wave.open(audio)
    signal = raw.readframes(-1)
    signal = np.frombuffer(signal, dtype="int16")
    f_rate = raw.getframerate()
    time = np.linspace(
        0,  # start
        len(signal) / f_rate,
        num=len(signal)
    )

    return time, signal, f_rate

def visualize(path: str):
    # reading the audio file
    raw = wave.open(path)

    # reads all the frames
    # -1 indicates all or max frames
    signal = raw.readframes(-1)
    signal = np.frombuffer(signal, dtype="int16")

    # gets the frame rate
    f_rate = raw.getframerate()

    # to Plot the x-axis in seconds
    # you need get the frame rate
    # and divide by size of your signal
    # to create a Time Vector
    # spaced linearly with the size
    # of the audio file
    time = np.linspace(
        0,  # start
        len(signal) / f_rate,
        num=len(signal)
    )

    # using matplotlib to plot
    # creates a new figure
    plt.figure(1)

    # title of the plot
    plt.title("Sound Wave")

    # label of x-axis
    plt.xlabel("Time")

    # actual plotting
    plt.plot(time, signal)

    # shows the plot
    # in new window
    plt.show()

    # you can also save
    # the plot using
    # plt.savefig('filename')


import requests
import os
import json
import csv

i = 1
response = requests.get(f"https://support.metamask.io/api/v2/help_center/articles.json?page={i}")

data = response.json()

page_count = data["page_count"]

file = open("articles.csv", "w", newline="")
writer = csv.writer(file)
writer.writerow(["Article", "URL", "Section"])

for page in range(i, page_count):
    response = requests.get(f"https://support.metamask.io/api/v2/help_center/articles.json?page={i}")
    data = response.json()
    for article in data["articles"]:
        writer.writerow([article["title"], article["html_url"], article["section_id"]])
    i += 1