import json
from adblockparser import AdblockRules
import os
import glob

def extract_ad_data_from_har(har_file_path, website_label):
    # Read EasyList rules from the file
    with open('/Users/shuaibahmed/Gunrock Breakerspace/URL:FL Matching/easylist.txt', 'r') as f:
        easylist_rules = f.read().splitlines()

    # Create AdblockRules instance with EasyList rules
    adblock_rules = AdblockRules(easylist_rules)

    # List to store extracted ad data
    ad_data_list = []
    header = f"FILE : {website_label}"
    ad_data_list.append(header)

    # Load the HAR file
    with open(har_file_path, 'r') as har_file:
        har_data = json.load(har_file)

    # Loop through all entries in the HAR file
    for entry in har_data['log']['entries']:
        request = entry['request']
        response = entry['response']
        url = request['url']

        resource_type = entry.get('_resourceType')

        # Set the desired matching options
        if resource_type == 'document':
            option = {'document': True, 'subdocument': True, 'third-party':True}
        elif resource_type == 'script':
            option = {'script': True, 'subdocument': True, 'third-party':True}
        elif resource_type == 'xhr':
            option = {'xmlhttprequest': True, 'subdocument': True, 'third-party':True}
        elif resource_type == 'image':
            option = {'image': True, 'subdocument': True, 'third-party':True}
        elif resource_type == 'object':
            option = {'object': True, 'subdocument': True, 'third-party':True}
        elif resource_type == 'stylesheet':
            option = {'stylesheet': True, 'subdocument': True, 'third-party':True}
        elif resource_type == 'elemhide':
            option = {'elemhide': True, 'subdocument': True, 'third-party':True}
        elif resource_type == 'background':
            option = {'background': True, 'subdocument': True, 'third-party':True}

        # Match ads on the URL using the AdblockRules instance
        if adblock_rules.should_block(url, option):

            ad_data = {
                'url': url,
                'dimensions': {
                    'width': request.get('width'),
                    'height': request.get('height')
                },
                'mime_type': response.get('content', {}).get('mimeType'),
                'status': response.get('status'),
                'status_text': response.get('statusText'),
                'headers': response.get('headers'),
                'request_headers': request.get('headers'),
            }

            ad_data_list.append(ad_data)

    seperator = '-------------------------------------------------------------------------------------------------------------'
    ad_data_list.append(seperator)

    return ad_data_list

def save_to_json(ad_data_list, filename):
    try:
        if os.path.isfile(filename):
            # Read the existing data from the file
            with open(filename, 'r') as f:
                try:
                    existing_data = json.load(f)
                except json.JSONDecodeError:
                    existing_data = []
        else:
            existing_data = []

        # Append the new data to the existing data
        existing_data.extend(ad_data_list)

        # Write the updated data back to the file
        with open(filename, 'w') as f:
            json.dump(existing_data, f, indent=4)
    except Exception as e:
        print("Error occurred while saving to JSON:", str(e))

def get_har_file_paths(directory):
    har_files = glob.glob(os.path.join(directory, '*.har'))
    return har_files

har_directory = '/Users/shuaibahmed/Gunrock Breakerspace/URL:FL Matching/HAR_files'
har_file_paths = get_har_file_paths(har_directory)

for har_file_path in har_file_paths:
    website_label = har_file_path
    ad_data_list = extract_ad_data_from_har(har_file_path, website_label)

    if ad_data_list:
        print("Ad data extracted from", har_file_path)
        save_to_json(ad_data_list, '100Realt.json')
        print("Ad data saved to 'ad_data.json' file.")
    else:
        print("No ads found in the HAR file", har_file_path)


from __future__ import absolute_import
import re
import six

from telemetry.story import shared_state as shared_state_module

_next_story_id = 0

_VALID_TAG_RE = re.compile(r'^[\w]+$')

class Story():
  """A class styled on unittest.TestCase for creating story tests.

  Tests should override Run to maybe start the application and perform actions
  on it. To share state between different tests, one can define a
  shared_state which contains hooks that will be called before and
  after multiple stories run and in between runs.

  Args:
    shared_state_class: subclass of telemetry.story.shared_state.SharedState.
    name: string name of this story that can be used for identifying this story
        in results output.
    tags: A list or set of string labels that are used for filtering. See
        story.story_filter for more information.
    is_local: If True, the story does not require network.
    grouping_keys: A dict of grouping keys that will be added to values computed
        on this story.
  """

  def __init__(self, shared_state_class, name='', tags=None,
               is_local=False, make_javascript_deterministic=True,
               grouping_keys=None, platform_specific=False):
    """
    Args:
      make_javascript_deterministic: Whether JavaScript performed on
          the page is made deterministic across multiple runs. This
          requires that the web content is served via Web Page Replay
          to take effect. This setting does not affect stories containing no web
          content or where the HTTP MIME type is not text/html.See also:
          _InjectScripts method in third_party/web-page-replay/httpclient.py.
      platform_specific: Boolean indicating if a separate web page replay
          recording is required on each platform.
    """
    assert issubclass(shared_state_class,
                      shared_state_module.SharedState)
    self._shared_state_class = shared_state_class
    assert name, 'All stories must be named.'
    self._name = name
    self._platform_specific = platform_specific
    global _next_story_id # pylint: disable=global-statement
    self._id = _next_story_id
    _next_story_id += 1
    if tags is None:
      tags = set()
    elif isinstance(tags, list):
      tags = set(tags)
    else:
      assert isinstance(tags, set)
    for t in tags:
      if not _VALID_TAG_RE.match(t):
        raise ValueError(
            'Invalid tag string: %s. Tag can only contain alphanumeric and '
            'underscore characters.' % t)
      if len(t) > 50:
        raise ValueError('Invalid tag string: %s. Tag can have at most 50 '
                         'characters')
    self._tags = tags
    self._is_local = is_local
    self._make_javascript_deterministic = make_javascript_deterministic
    if grouping_keys is None:
      grouping_keys = {}
    else:
      assert isinstance(grouping_keys, dict)
    self._grouping_keys = grouping_keys
    # A cache of the shared state wpr_mode to make it available to a story.
    self.wpr_mode = None

  def Run(self, shared_state):
    """Execute the interactions with the applications and/or platforms."""
    raise NotImplementedError

  @property
  def tags(self):
    return self._tags

  @property
  def shared_state_class(self):
    return self._shared_state_class

  @property
  def id(self):
    return self._id

  @property
  def name(self):
    return self._name

  @property
  def grouping_keys(self):
    return self._grouping_keys

  @property
  def name_and_grouping_key_tuple(self):
    return self.name, tuple(six.iteritems(self.grouping_keys))

  def AsDict(self):
    """Converts a story object to a dict suitable for JSON output."""
    d = {
        'id': self._id,
    }
    if self._name:
      d['name'] = self._name
    return d

  @property
  def file_safe_name(self):
    """A version of display_name that's safe to use as a filename.

    The default implementation sanitizes special characters with underscores,
    but it's okay to override it with a more specific implementation in
    subclasses.
    """
    # This fail-safe implementation is safe for subclasses to override.
    return re.sub('[^a-zA-Z0-9]', '_', self.name)

  @property
  def is_local(self):
    """Returns True iff this story does not require network."""
    return self._is_local

  @property
  def serving_dir(self):
    """Returns the absolute path to a directory with hash files to data that
       should be updated from cloud storage, or None if no files need to be
       updated.
    """
    return None

  @property
  def make_javascript_deterministic(self):
    return self._make_javascript_deterministic

  @property
  def platform_specific(self):
    return self._platform_specific

  def GetStoryTagsList(self):
    """Return a list of strings with story tags and grouping keys."""
    return sorted(list(self.tags)) + [
        '%s:%s' % kv for kv in six.iteritems(self.grouping_keys)]

  def GetExtraTracingMetrics(self):
    """Override this to add more TBMv2 metrics to be computed.

    These metrics were originally set up by the benchmark in
    CreateCoreTimelineBasedMeasurementOptions. This method provides the page
    with a way to add more metrics in the case that certain pages need more
    metrics than others. This is reasonable to do if certain pages within
    your benchmark do not provide the
    information needed to calculate various metrics, or if those metrics
    are not important for that page.

    This option only works for TBMv2 metrics.

    You should return a list of the names of the metrics. For example,
    return ['exampleMetric']
    """
    return []

  def WillStartTracing(self, chrome_trace_config):
    """This method provides a way to add/modify tracing configs on the story
    levels. e.g. if you want to add more trace categories for some stories
    you can add them here.
    """


import sys, subprocess, os
import xml.etree.ElementTree as et
from ptxprint.utils import pt_bindir

if sys.platform == "linux":

    def fclist(family, pattern):
        a = ["fc-list", '"{0}":style="{1}"'.format(family, pattern), 'file']
        return subprocess.check_output(" ".join(a), shell=1).decode("utf-8", errors="ignore")

    def checkoutput(*a, **kw):
        if 'path' in kw:
            del kw['path']
        res = subprocess.check_output(*a, **kw).decode("utf-8", errors="ignore")
        return res

    def call(*a, **kw):
        return subprocess.call(*a, **kw)

elif sys.platform == "win32":
    CREATE_NO_WINDOW = 0x08000000

    def fclist(family, pattern):
        a = [os.path.join(pt_bindir(), "xetex", "bin", "windows", "fc-list.exe").replace("\\", "/"),
                '"'+family+'"', '":style='+pattern+'"', 'file']
        return subprocess.check_output(a, creationflags=CREATE_NO_WINDOW).decode("utf-8", errors="ignore")

    def checkoutput(*a, **kw):
        if 'shell' in kw:
            del kw['shell']
        if 'path' in kw:
            if kw['path'] == 'xetex':
                path = os.path.join(pt_bindir(), "xetex", "bin", "windows", a[0][0]+".exe").replace("\\", "/")
                a = [[path] + list(a[0])[1:]] + [x.replace('"', '') for x in a[1:]]
            del kw['path']
        else:
            a = [[x.replace("/", "\\") for x in a[0]]] + [x.replace('"', '') for x in a[1:]]
        res = subprocess.check_output(*a, creationflags=CREATE_NO_WINDOW, **kw).decode("utf-8", errors="ignore")
        return res

    def call(*a, **kw):
        path = os.path.join(pt_bindir(), "xetex", "bin", "windows", a[0][0]+".exe").replace("/", "\\")
        newa = [[path] + a[0][1:]] + list(a)[1:]
        res = subprocess.call(*newa, creationflags=CREATE_NO_WINDOW, **kw)
        return res


tanyai=['kok','?','apa','tau','tahu','apakah','sih','siapa','dimana','mengapa','bagaimana','kenapa','ngapain']
me=['gw','saya','ane','ana','gua','gue','saya','aku']
you=['lu','kamu','anda','lo','loe','bot','botnya']
tanya={
    "?":100,
    "apa":100,
    "apakah":100,
    "siapa":100,
    "dimana":100,
    "mengapa":100,
    "bagaimana":100,
    "kenapa":100,
    "tau":20,
    "tahu":20,
    "ngapain":60,
    "kok":60
}
#---------------------------
def fobjek(kalimat):
    otput=[]
    k=kalimat.replace('?','')
    seplit = k.lower().split(" ")
    for x in seplit:
        if x in me:
            otput.append('dia')
        if x in you:
            otput.append('botnya')
    if len(otput)>1:
        return 'bisa siapa aja'
    elif len(otput)==1:
        return otput[0]
    else:
        return 'yang di tanya'

def fjenis(kalimat):
    cond=False
    percent = 1
    otput = ""

    seplit = kalimat.split(" ")
    for x in seplit:
        if "?" in x:
            percent +=100
            x = x.replace("?","")
        if x in tanyai:
            itanyai = tanyai.index(x)
            percent += tanya[tanyai[itanyai]]
            otput += x

    if percent >= 100:
        percent = 100

    try:
        ptanya = str((percent-0)/percent)+"%"
        pnyata = str((100-percent)/percent)+"%"
    except:
        ptanya = "unknown"
        pnyata = "unknown"

    otput += "\n"+str(percent)+"\n"
    otput += "\npertanyaan : "+ptanya
    otput += "\npernyataan : "+pnyata

    if ptanya>pnyata:
        cond=True
    else:
        cond=False
    return cond
#---------------------------


from datetime import date

from models.checkpoint import Checkpoint
from models.events import Event
from models.private_mentoring import PrivateMentoring

from views import view

def start_controller(user):
    """
    Contain main logic of controller,
    call functions to perform task choosen by user

    Raises:
        FileNotFoundError: if file to open is not present
    """

    try:
        Checkpoint.read_events()
    except FileNotFoundError as err:
        view.print_msg(err)
        pass

    try:
        PrivateMentoring.read_events()
    except FileNotFoundError as err:
        view.print_msg(err)
        pass

    choice = None

    head = "Chose option:"
    options_list = ["Book private mentoring",
                    "Show all my events",
                    "Cancel event",
                    "Reschedule event"
                    ]
    exit_msg = "Exit program"

    while choice != "0":
        view.print_msg("\nWelcome {} {}".format(user.name, user.surname))
        view.print_menu(head, options_list, exit_msg)
        choice = view.get_choice()
        if choice == "1":
            book_private_mentoring(user.user_id)
        elif choice == "2":
            display_user_evets(user.user_id)
        elif choice == "3":
            cancel_event(user.user_id)
        elif choice == "4":
            reschedule_event(user.user_id)
        elif choice == "0":
            say_goodbye()
        else:
            view.print_msg("Wrong option!\n")

    Checkpoint.save_events()
    PrivateMentoring.save_events()

def display_user_evets(user_id):
    """
    Call function to print all user private mentoring
    and checkpoints Events objects to user

    Examples:
        "mt" are two first signs of mentor id
    """

    user_events = []

    events = Event.get_events()
    for event in events:
        if event.user_id == user_id or event.__class__.__name__ == "Checkpoint":
            user_events.append(event)

    view.print_all_events(user_events)

def book_private_mentoring(user_id):
    """
    Call functions that allow user create PrivateMentoring object
    """

    date = view.get_event_date()

    date = validate_date(date)
    preffered_mentor = choice_preffered_mentor()
    goal = view.get_goal()

    if date is not None and preffered_mentor is not None and goal:

        PrivateMentoring(date, goal, preffered_mentor, user_id)

    else:
        view.print_msg("Mentoring not scheduled!")

def say_goodbye():
    """
    Call function that print goodbye massage to user
    """

    view.print_goodbye()

def convert_date(date_str):
    """
    Convert data from string to date object

    Args:
        date_str: date of event choose by user

    Returns:
        :obj: `date`: date of event choose by user
    """

    date_list = date_str.split('-')
    return date(int(date_list[2]), int(date_list[1]), int(date_list[0]))

def cancel_event(user_id):
    """
    Call functions to cancel event
    """

    choice = None
    temp_event_list = []

    for event in Event.events:
        if event.__class__.__name__ == "PrivateMentoring" and event.user_id == user_id:
            temp_event_list.append(event)

    head = "Chose option:"
    exit_msg = "Exit event cancelation"

    view.print_menu(head, temp_event_list, exit_msg)

    choice = view.get_choice()
    choice = int(choice) - 1

    if choice == - 1:
        pass
    elif choice >= len(temp_event_list):
        view.print_msg("No such event!\n")
    else:
        PrivateMentoring.del_event(temp_event_list[choice])

def reschedule_event(user_id):
    """
    Call functions to change event date
    """

    choice = None
    temp_event_list = []

    for event in Event.events:
        if event.__class__.__name__ == "PrivateMentoring" and event.user_id == user_id:
            temp_event_list.append(event)

    head = "Chose option:"
    exit_msg = "Exit event reschedule"

    view.print_menu(head, temp_event_list, exit_msg)

    choice = view.get_choice()
    choice = int(choice) - 1

    if choice == - 1:
        pass
    elif choice >= len(temp_event_list):
        view.print_msg("No such event!\n")
    else:

        view.print_msg("Enter new event date")
        new_date = view.get_event_date()

        new_date = validate_date(new_date)

        if new_date is not None:
            Event.change_date(temp_event_list[choice], new_date)

def validate_date(date_str, future_date=True):
    """
    Validate if given date is correct
    and if parametr future_date set tu True check if date is in future

    Args:
        date_str: date of event choose by user

    Returns:
        :obj: `date`: date of event choose by user

    Raises:
        ValueError: if string given to convert have letters or
        scope of numbers are to low or high
        IndexError: if given string have to little delimiters as sing "-"
    """

    try:
        date = convert_date(date_str)
    except (ValueError, IndexError):
        view.print_msg("Wrong data format!\n")
    else:
        if future_date:
            if date <= date.today():
                view.print_msg("Date have to be in future!\n")
            else:
                return date
        else:
            return date

def choice_preffered_mentor():
    """
    Call functions to diplay manu and choose preferred mentor
    """

    AVAIALBLE_OPTIONS_LIST = ["0", "1", "2", "3", "4", "5"]

    choice = None
    preffered_mentor = None

    head = "Chose option:"
    options_list = ["Mateusz Ostafi",
                    "Agnieszka Koszany",
                    "Dominik Starzyk",
                    "Mateusz Steliga",
                    "Marcin Izworski"
                    ]
    exit_msg = "Exit booking provate mentoring"

    while choice not in AVAIALBLE_OPTIONS_LIST:
        view.print_menu(head, options_list, exit_msg)
        choice = view.get_choice()
        if choice == "1":
            preffered_mentor = "Mateusz Ostafi"
        elif choice == "2":
            preffered_mentor = "Agnieszka Koszany"
        elif choice == "3":
            preffered_mentor = "Dominik Starzyk"
        elif choice == "4":
            preffered_mentor = "Mateusz Steliga"
        elif choice == "5":
            preffered_mentor = "Marcin Izworski"
        elif choice == "0":
            view.print_msg("End of booking")
        else:
            view.print_msg("Wrong option!")

    return preffered_mentor


from http import HTTPStatus

from django.contrib.auth import get_user_model
from django.test import TestCase, Client

User = get_user_model()

class PostURLTests(TestCase):
    def setUp(self):
        self.guest_client = Client()

    def test_urls_exist_at_desired_location_guest(self):
        urls = [
            ('/about/author/'),
            ('/about/tech/'),
        ]
        for address in urls:
            with self.subTest(address=address):
                response = self.guest_client.get(address)
                self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_urls_uses_correct_template(self):
        templates_url_names = [
            ('/about/author/', 'about/resume.html'),
            ('/about/tech/', 'about/tech.html'),
        ]
        for address, template in templates_url_names:
            with self.subTest(address=address):
                response = self.guest_client.get(address)
                self.assertTemplateUsed(response, template)


# File 1 - library.py

# Catch Building of Classes

class Base:
    def foo(self):
        return self.bar()

old_bc = __build_class__
def my_bc(fun, name, base=None, **kw):
    if base is Base:
        print('Check if bar method defined')
    if base is not None:
        return old_bc(fun, name, base, **kw)
    return old_bc(fun, name, **kw)

import builtins
builtins.__build_class__ = my_bc


import asyncio
import os
import subprocess
import time

import pytest

from alsa_midi import WRITE_PORT, Address, ALSAError, AsyncSequencerClient, Event
from alsa_midi.client import SequencerClientBase

TESTS_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(TESTS_DIR, "data")

@pytest.mark.require_tool("aplaymidi")
@pytest.mark.require_alsa_seq
@pytest.mark.asyncio
async def test_event_input(asyncio_latency_check):
    client = AsyncSequencerClient("test")
    port = client.create_port("input", WRITE_PORT)

    # flush any 'port connect' events that could been emitted by some session
    # managers auto-connecting stuff
    await asyncio.sleep(1)
    client.drop_input()

    # should fail with EAGAIN
    with pytest.raises(ALSAError):
        SequencerClientBase.event_input(client)

    # should block for 0.5s
    start = time.monotonic()
    event = await client.event_input(timeout=2)
    assert event is None
    assert time.monotonic() - start >= 2.0

    # play a midi file to our port
    await asyncio_latency_check.stop()
    filename = os.path.join(DATA_DIR, "c_major.mid")
    cmd = ["aplaymidi", "-p", str(Address(port)), "-d", "0", filename]
    player = subprocess.Popen(cmd)

    # give it a bit time to start, the VM might be slow
    await asyncio.sleep(0.5)
    await asyncio_latency_check.cont()

    events = []
    # 1 port subscribe, 8 note-on,  8 note-off, 1 port unsubscribe
    for _ in range(18):
        event = await client.event_input(timeout=2)
        assert isinstance(event, Event)
        events.append(event)

    # should block for 0.5s (no more events)
    start = time.monotonic()
    event = await client.event_input(timeout=2)
    assert event is None
    assert time.monotonic() - start >= 2.0

    await asyncio_latency_check.stop()
    player.wait()
    await asyncio_latency_check.cont()

    assert (await asyncio_latency_check.get_max()) < 1


from __future__ import print_function
from __future__ import absolute_import
#author: Bryan Bishop <kanzure@gmail.com>
#date: 2012-01-09
from . import extract_maps
import os
import json
from copy import copy, deepcopy
from .pretty_map_headers import random_hash, map_name_cleaner
from ctypes import c_int8
import sys

spacing = "\t"

temp_opt_table = [
  [ "ADC A", 0x8f, 0 ],
  [ "ADC B", 0x88, 0 ],
  [ "ADC C", 0x89, 0 ],
  [ "ADC D", 0x8a, 0 ],
  [ "ADC E", 0x8b, 0 ],
  [ "ADC H", 0x8c, 0 ],
  [ "ADC [HL]", 0x8e, 0 ],
  [ "ADC L", 0x8d, 0 ],
  [ "ADC x", 0xce, 1 ],
  [ "ADD A", 0x87, 0 ],
  [ "ADD B", 0x80, 0 ],
  [ "ADD C", 0x81, 0 ],
  [ "ADD D", 0x82, 0 ],
  [ "ADD E", 0x83, 0 ],
  [ "ADD H", 0x84, 0 ],
  [ "ADD [HL]", 0x86, 0 ],
  [ "ADD HL, BC", 0x9, 0 ],
  [ "ADD HL, DE", 0x19, 0 ],
  [ "ADD HL, HL", 0x29, 0 ],
  [ "ADD HL, SP", 0x39, 0 ],
  [ "ADD L", 0x85, 0 ],
  [ "ADD SP, x", 0xe8, 1 ],
  [ "ADD x", 0xc6, 1 ],
  [ "AND A", 0xa7, 0 ],
  [ "AND B", 0xa0, 0 ],
  [ "AND C", 0xa1, 0 ],
  [ "AND D", 0xa2, 0 ],
  [ "AND E", 0xa3, 0 ],
  [ "AND H", 0xa4, 0 ],
  [ "AND [HL]", 0xa6, 0 ],
  [ "AND L", 0xa5, 0 ],
  [ "AND x", 0xe6, 1 ],
  [ "BIT 0, A", 0x47cb, 3 ],
  [ "BIT 0, B", 0x40cb, 3 ],
  [ "BIT 0, C", 0x41cb, 3 ],
  [ "BIT 0, D", 0x42cb, 3 ],
  [ "BIT 0, E", 0x43cb, 3 ],
  [ "BIT 0, H", 0x44cb, 3 ],
  [ "BIT 0, [HL]", 0x46cb, 3 ],
  [ "BIT 0, L", 0x45cb, 3 ],
  [ "BIT 1, A", 0x4fcb, 3 ],
  [ "BIT 1, B", 0x48cb, 3 ],
  [ "BIT 1, C", 0x49cb, 3 ],
  [ "BIT 1, D", 0x4acb, 3 ],
  [ "BIT 1, E", 0x4bcb, 3 ],
  [ "BIT 1, H", 0x4ccb, 3 ],
  [ "BIT 1, [HL]", 0x4ecb, 3 ],
  [ "BIT 1, L", 0x4dcb, 3 ],
  [ "BIT 2, A", 0x57cb, 3 ],
  [ "BIT 2, B", 0x50cb, 3 ],
  [ "BIT 2, C", 0x51cb, 3 ],
  [ "BIT 2, D", 0x52cb, 3 ],
  [ "BIT 2, E", 0x53cb, 3 ],
  [ "BIT 2, H", 0x54cb, 3 ],
  [ "BIT 2, [HL]", 0x56cb, 3 ],
  [ "BIT 2, L", 0x55cb, 3 ],
  [ "BIT 3, A", 0x5fcb, 3 ],
  [ "BIT 3, B", 0x58cb, 3 ],
  [ "BIT 3, C", 0x59cb, 3 ],
  [ "BIT 3, D", 0x5acb, 3 ],
  [ "BIT 3, E", 0x5bcb, 3 ],
  [ "BIT 3, H", 0x5ccb, 3 ],
  [ "BIT 3, [HL]", 0x5ecb, 3 ],
  [ "BIT 3, L", 0x5dcb, 3 ],
  [ "BIT 4, A", 0x67cb, 3 ],
  [ "BIT 4, B", 0x60cb, 3 ],
  [ "BIT 4, C", 0x61cb, 3 ],
  [ "BIT 4, D", 0x62cb, 3 ],
  [ "BIT 4, E", 0x63cb, 3 ],
  [ "BIT 4, H", 0x64cb, 3 ],
  [ "BIT 4, [HL]", 0x66cb, 3 ],
  [ "BIT 4, L", 0x65cb, 3 ],
  [ "BIT 5, A", 0x6fcb, 3 ],
  [ "BIT 5, B", 0x68cb, 3 ],
  [ "BIT 5, C", 0x69cb, 3 ],
  [ "BIT 5, D", 0x6acb, 3 ],
  [ "BIT 5, E", 0x6bcb, 3 ],
  [ "BIT 5, H", 0x6ccb, 3 ],
  [ "BIT 5, [HL]", 0x6ecb, 3 ],
  [ "BIT 5, L", 0x6dcb, 3 ],
  [ "BIT 6, A", 0x77cb, 3 ],
  [ "BIT 6, B", 0x70cb, 3 ],
  [ "BIT 6, C", 0x71cb, 3 ],
  [ "BIT 6, D", 0x72cb, 3 ],
  [ "BIT 6, E", 0x73cb, 3 ],
  [ "BIT 6, H", 0x74cb, 3 ],
  [ "BIT 6, [HL]", 0x76cb, 3 ],
  [ "BIT 6, L", 0x75cb, 3 ],
  [ "BIT 7, A", 0x7fcb, 3 ],
  [ "BIT 7, B", 0x78cb, 3 ],
  [ "BIT 7, C", 0x79cb, 3 ],
  [ "BIT 7, D", 0x7acb, 3 ],
  [ "BIT 7, E", 0x7bcb, 3 ],
  [ "BIT 7, H", 0x7ccb, 3 ],
  [ "BIT 7, [HL]", 0x7ecb, 3 ],
  [ "BIT 7, L", 0x7dcb, 3 ],
  [ "CALL C, ?", 0xdc, 2 ],
  [ "CALL NC, ?", 0xd4, 2 ],
  [ "CALL NZ, ?", 0xc4, 2 ],
  [ "CALL Z, ?", 0xcc, 2 ],
  [ "CALL ?", 0xcd, 2 ],
  [ "CCF", 0x3f, 0 ],
  [ "CP A", 0xbf, 0 ],
  [ "CP B", 0xb8, 0 ],
  [ "CP C", 0xb9, 0 ],
  [ "CP D", 0xba, 0 ],
  [ "CP E", 0xbb, 0 ],
  [ "CP H", 0xbc, 0 ],
  [ "CP [HL]", 0xbe, 0 ],
  [ "CPL", 0x2f, 0 ],
  [ "CP L", 0xbd, 0 ],
  [ "CP x", 0xfe, 1 ],
  [ "DAA", 0x27, 0 ],
  [ "DEBUG", 0xed, 0 ],
  [ "DEC A", 0x3d, 0 ],
  [ "DEC B", 0x5, 0 ],
  [ "DEC BC", 0xb, 0 ],
  [ "DEC C", 0xd, 0 ],
  [ "DEC D", 0x15, 0 ],
  [ "DEC DE", 0x1b, 0 ],
  [ "DEC E", 0x1d, 0 ],
  [ "DEC H", 0x25, 0 ],
  [ "DEC HL", 0x2b, 0 ],
  [ "DEC [HL]", 0x35, 0 ],
  [ "DEC L", 0x2d, 0 ],
  [ "DEC SP", 0x3b, 0 ],
  [ "DI", 0xf3, 0 ],
  [ "EI", 0xfb, 0 ],
  [ "HALT", 0x76, 0 ],
  [ "INC A", 0x3c, 0 ],
  [ "INC B", 0x4, 0 ],
  [ "INC BC", 0x3, 0 ],
  [ "INC C", 0xc, 0 ],
  [ "INC D", 0x14, 0 ],
  [ "INC DE", 0x13, 0 ],
  [ "INC E", 0x1c, 0 ],
  [ "INC H", 0x24, 0 ],
  [ "INC HL", 0x23, 0 ],
  [ "INC [HL]", 0x34, 0 ],
  [ "INC L", 0x2c, 0 ],
  [ "INC SP", 0x33, 0 ],
  [ "JP C, ?", 0xda, 2 ],
  [ "JP HL", 0xe9, 0 ],
  [ "JP NC, ?", 0xd2, 2 ],
  [ "JP NZ, ?", 0xc2, 2 ],
  [ "JP Z, ?", 0xca, 2 ],
  [ "JP ?", 0xc3, 2 ],
  [ "JR C, x", 0x38, 1 ],
  [ "JR NC, x", 0x30, 1 ],
  [ "JR NZ, x", 0x20, 1 ],
  [ "JR Z, x", 0x28, 1 ],
  [ "JR x", 0x18, 1 ],
  [ "LD A, A", 0x7f, 0 ],
  [ "LD A, B", 0x78, 0 ],
  [ "LD A, C", 0x79, 0 ],
  [ "LD A, D", 0x7a, 0 ],
  [ "LD A, E", 0x7b, 0 ],
  [ "LD A, H", 0x7c, 0 ],
  [ "LD A, L", 0x7d, 0 ],
  [ "LD A, [$FF00+C]", 0xf2, 0 ],
  [ "LD A, [$FF00+x]", 0xf0, 1 ],
#  [ "LDH A, [x]", 0xf0, 1 ], #rgbds has trouble with this one?
  [ "LD A, [BC]", 0xa, 0 ],
  [ "LD A, [DE]", 0x1a, 0 ],
#  [ "LD A, [HL+]", 0x2a, 0 ],
#  [ "LD A, [HL-]", 0x3a, 0 ],
  [ "LD A, [HL]", 0x7e, 0 ],
  [ "LD A, [HLD]", 0x3a, 0 ],
  [ "LD A, [HLI]", 0x2a, 0 ],
  [ "LD A, [?]", 0xfa, 2 ],
  [ "LD A, x", 0x3e, 1 ],
  [ "LD B, A", 0x47, 0 ],
  [ "LD B, B", 0x40, 0 ],
  [ "LD B, C", 0x41, 0 ],
  [ "LD [BC], A", 0x2, 0 ],
  [ "LD B, D", 0x42, 0 ],
  [ "LD B, E", 0x43, 0 ],
  [ "LD B, H", 0x44, 0 ],
  [ "LD B, [HL]", 0x46, 0 ],
  [ "LD B, L", 0x45, 0 ],
  [ "LD B, x", 0x6, 1 ],
  [ "LD C, A", 0x4f, 0 ],
  [ "LD C, B", 0x48, 0 ],
  [ "LD C, C", 0x49, 0 ],
  [ "LD C, D", 0x4a, 0 ],
  [ "LD C, E", 0x4b, 0 ],
  [ "LD C, H", 0x4c, 0 ],
  [ "LD C, [HL]", 0x4e, 0 ],
  [ "LD C, L", 0x4d, 0 ],
  [ "LD C, x", 0xe, 1 ],
  [ "LD D, A", 0x57, 0 ],
#  [ "LDD A, [HL]", 0x3a, 0 ],
  [ "LD D, B", 0x50, 0 ],
  [ "LD D, C", 0x51, 0 ],
  [ "LD D, D", 0x52, 0 ],
  [ "LD D, E", 0x53, 0 ],
  [ "LD [DE], A", 0x12, 0 ],
  [ "LD D, H", 0x54, 0 ],
  [ "LD D, [HL]", 0x56, 0 ],
#  [ "LDD [HL], A", 0x32, 0 ],
  [ "LD D, L", 0x55, 0 ],
  [ "LD D, x", 0x16, 1 ],
  [ "LD E, A", 0x5f, 0 ],
  [ "LD E, B", 0x58, 0 ],
  [ "LD E, C", 0x59, 0 ],
  [ "LD E, D", 0x5a, 0 ],
  [ "LD E, E", 0x5b, 0 ],
  [ "LD E, H", 0x5c, 0 ],
  [ "LD E, [HL]", 0x5e, 0 ],
  [ "LD E, L", 0x5d, 0 ],
  [ "LD E, x", 0x1e, 1 ],
  [ "LD [$FF00+C], A", 0xe2, 0 ],
  [ "LD [$FF00+x], A", 0xe0, 1 ],
#  [ "LDH [x], A", 0xe0, 1 ],
  [ "LD H, A", 0x67, 0 ],
  [ "LD H, B", 0x60, 0 ],
  [ "LD H, C", 0x61, 0 ],
  [ "LD H, D", 0x62, 0 ],
  [ "LD H, E", 0x63, 0 ],
  [ "LD H, H", 0x64, 0 ],
  [ "LD H, [HL]", 0x66, 0 ],
  [ "LD H, L", 0x65, 0 ],
#  [ "LD [HL+], A", 0x22, 0 ],
#  [ "LD [HL-], A", 0x32, 0 ],
  [ "LD [HL], A", 0x77, 0 ],
  [ "LD [HL], B", 0x70, 0 ],
  [ "LD [HL], C", 0x71, 0 ],
  [ "LD [HL], D", 0x72, 0 ],
  [ "LD [HLD], A", 0x32, 0 ],
  [ "LD [HL], E", 0x73, 0 ],
  [ "LD [HL], H", 0x74, 0 ],
  [ "LD [HLI], A", 0x22, 0 ],
  [ "LD [HL], L", 0x75, 0 ],
  [ "LD HL, SP+x", 0xf8, 1 ],
  [ "LD [HL], x", 0x36, 1 ],
  [ "LD H, x", 0x26, 1 ],
#  [ "LDI A, [HL]", 0x2a, 0 ],
#  [ "LDI [HL], A", 0x22, 0 ],
  [ "LD L, A", 0x6f, 0 ],
  [ "LD L, B", 0x68, 0 ],
  [ "LD L, C", 0x69, 0 ],
  [ "LD L, D", 0x6a, 0 ],
  [ "LD L, E", 0x6b, 0 ],
  [ "LD L, H", 0x6c, 0 ],
  [ "LD L, [HL]", 0x6e, 0 ],
  [ "LD L, L", 0x6d, 0 ],
  [ "LD L, x", 0x2e, 1 ],
#  [ "LD PC, HL", 0xe9, 0 ], #prefer jp [hl]
  [ "LD SP, HL", 0xf9, 0 ],
  [ "LD BC, ?", 0x1, 2 ],
  [ "LD DE, ?", 0x11, 2 ],
  [ "LD HL, ?", 0x21, 2 ],
  [ "LD SP, ?", 0x31, 2 ],
#  [ "LD [?], SP", 0x8, 2 ],
  [ "LD [?], A", 0xea, 2 ],
  [ "NOP", 0x0, 0 ],
  [ "OR A", 0xb7, 0 ],
  [ "OR B", 0xb0, 0 ],
  [ "OR C", 0xb1, 0 ],
  [ "OR D", 0xb2, 0 ],
  [ "OR E", 0xb3, 0 ],
  [ "OR H", 0xb4, 0 ],
  [ "OR [HL]", 0xb6, 0 ],
  [ "OR L", 0xb5, 0 ],
  [ "OR x", 0xf6, 1 ],
  [ "POP AF", 0xf1, 0 ],
  [ "POP BC", 0xc1, 0 ],
  [ "POP DE", 0xd1, 0 ],
  [ "POP HL", 0xe1, 0 ],
  [ "PUSH AF", 0xf5, 0 ],
  [ "PUSH BC", 0xc5, 0 ],
  [ "PUSH DE", 0xd5, 0 ],
  [ "PUSH HL", 0xe5, 0 ],
  [ "RES 0, A", 0x87cb, 3 ],
  [ "RES 0, B", 0x80cb, 3 ],
  [ "RES 0, C", 0x81cb, 3 ],
  [ "RES 0, D", 0x82cb, 3 ],
  [ "RES 0, E", 0x83cb, 3 ],
  [ "RES 0, H", 0x84cb, 3 ],
  [ "RES 0, [HL]", 0x86cb, 3 ],
  [ "RES 0, L", 0x85cb, 3 ],
  [ "RES 1, A", 0x8fcb, 3 ],
  [ "RES 1, B", 0x88cb, 3 ],
  [ "RES 1, C", 0x89cb, 3 ],
  [ "RES 1, D", 0x8acb, 3 ],
  [ "RES 1, E", 0x8bcb, 3 ],
  [ "RES 1, H", 0x8ccb, 3 ],
  [ "RES 1, [HL]", 0x8ecb, 3 ],
  [ "RES 1, L", 0x8dcb, 3 ],
  [ "RES 2, A", 0x97cb, 3 ],
  [ "RES 2, B", 0x90cb, 3 ],
  [ "RES 2, C", 0x91cb, 3 ],
  [ "RES 2, D", 0x92cb, 3 ],
  [ "RES 2, E", 0x93cb, 3 ],
  [ "RES 2, H", 0x94cb, 3 ],
  [ "RES 2, [HL]", 0x96cb, 3 ],
  [ "RES 2, L", 0x95cb, 3 ],
  [ "RES 3, A", 0x9fcb, 3 ],
  [ "RES 3, B", 0x98cb, 3 ],
  [ "RES 3, C", 0x99cb, 3 ],
  [ "RES 3, D", 0x9acb, 3 ],
  [ "RES 3, E", 0x9bcb, 3 ],
  [ "RES 3, H", 0x9ccb, 3 ],
  [ "RES 3, [HL]", 0x9ecb, 3 ],
  [ "RES 3, L", 0x9dcb, 3 ],
  [ "RES 4, A", 0xa7cb, 3 ],
  [ "RES 4, B", 0xa0cb, 3 ],
  [ "RES 4, C", 0xa1cb, 3 ],
  [ "RES 4, D", 0xa2cb, 3 ],
  [ "RES 4, E", 0xa3cb, 3 ],
  [ "RES 4, H", 0xa4cb, 3 ],
  [ "RES 4, [HL]", 0xa6cb, 3 ],
  [ "RES 4, L", 0xa5cb, 3 ],
  [ "RES 5, A", 0xafcb, 3 ],
  [ "RES 5, B", 0xa8cb, 3 ],
  [ "RES 5, C", 0xa9cb, 3 ],
  [ "RES 5, D", 0xaacb, 3 ],
  [ "RES 5, E", 0xabcb, 3 ],
  [ "RES 5, H", 0xaccb, 3 ],
  [ "RES 5, [HL]", 0xaecb, 3 ],
  [ "RES 5, L", 0xadcb, 3 ],
  [ "RES 6, A", 0xb7cb, 3 ],
  [ "RES 6, B", 0xb0cb, 3 ],
  [ "RES 6, C", 0xb1cb, 3 ],
  [ "RES 6, D", 0xb2cb, 3 ],
  [ "RES 6, E", 0xb3cb, 3 ],
  [ "RES 6, H", 0xb4cb, 3 ],
  [ "RES 6, [HL]", 0xb6cb, 3 ],
  [ "RES 6, L", 0xb5cb, 3 ],
  [ "RES 7, A", 0xbfcb, 3 ],
  [ "RES 7, B", 0xb8cb, 3 ],
  [ "RES 7, C", 0xb9cb, 3 ],
  [ "RES 7, D", 0xbacb, 3 ],
  [ "RES 7, E", 0xbbcb, 3 ],
  [ "RES 7, H", 0xbccb, 3 ],
  [ "RES 7, [HL]", 0xbecb, 3 ],
  [ "RES 7, L", 0xbdcb, 3 ],
  [ "RETI", 0xd9, 0 ],
  [ "RET C", 0xd8, 0 ],
  [ "RET NC", 0xd0, 0 ],
  [ "RET NZ", 0xc0, 0 ],
  [ "RET Z", 0xc8, 0 ],
  [ "RET", 0xc9, 0 ],
  [ "RLA", 0x17, 0 ],
  [ "RL A", 0x17cb, 3 ],
  [ "RL B", 0x10cb, 3 ],
  [ "RL C", 0x11cb, 3 ],
  [ "RLCA", 0x7, 0 ],
  [ "RLC A", 0x7cb, 3 ],
  [ "RLC B", 0xcb, 3 ],
  [ "RLC C", 0x1cb, 3 ],
  [ "RLC D", 0x2cb, 3 ],
  [ "RLC E", 0x3cb, 3 ],
  [ "RLC H", 0x4cb, 3 ],
  [ "RLC [HL]", 0x6cb, 3 ],
  [ "RLC L", 0x5cb, 3 ],
  [ "RL D", 0x12cb, 3 ],
  [ "RL E", 0x13cb, 3 ],
  [ "RL H", 0x14cb, 3 ],
  [ "RL [HL]", 0x16cb, 3 ],
  [ "RL L", 0x15cb, 3 ],
  [ "RRA", 0x1f, 0 ],
  [ "RR A", 0x1fcb, 3 ],
  [ "RR B", 0x18cb, 3 ],
  [ "RR C", 0x19cb, 3 ],
  [ "RRCA", 0xf, 0 ],
  [ "RRC A", 0xfcb, 3 ],
  [ "RRC B", 0x8cb, 3 ],
  [ "RRC C", 0x9cb, 3 ],
  [ "RRC D", 0xacb, 3 ],
  [ "RRC E", 0xbcb, 3 ],
  [ "RRC H", 0xccb, 3 ],
  [ "RRC [HL]", 0xecb, 3 ],
  [ "RRC L", 0xdcb, 3 ],
  [ "RR D", 0x1acb, 3 ],
  [ "RR E", 0x1bcb, 3 ],
  [ "RR H", 0x1ccb, 3 ],
  [ "RR [HL]", 0x1ecb, 3 ],
  [ "RR L", 0x1dcb, 3 ],
  [ "RST $0", 0xc7, 0 ],
  [ "RST $10", 0xd7, 0 ],
  [ "RST $18", 0xdf, 0 ],
  [ "RST $20", 0xe7, 0 ],
  [ "RST $28", 0xef, 0 ],
  [ "RST $30", 0xf7, 0 ],
  [ "RST $38", 0xff, 0 ],
  [ "RST $8", 0xcf, 0 ],
  [ "SBC A", 0x9f, 0 ],
  [ "SBC B", 0x98, 0 ],
  [ "SBC C", 0x99, 0 ],
  [ "SBC D", 0x9a, 0 ],
  [ "SBC E", 0x9b, 0 ],
  [ "SBC H", 0x9c, 0 ],
  [ "SBC [HL]", 0x9e, 0 ],
  [ "SBC L", 0x9d, 0 ],
  [ "SBC x", 0xde, 1 ],
  [ "SCF", 0x37, 0 ],
  [ "SET 0, A", 0xc7cb, 3 ],
  [ "SET 0, B", 0xc0cb, 3 ],
  [ "SET 0, C", 0xc1cb, 3 ],
  [ "SET 0, D", 0xc2cb, 3 ],
  [ "SET 0, E", 0xc3cb, 3 ],
  [ "SET 0, H", 0xc4cb, 3 ],
  [ "SET 0, [HL]", 0xc6cb, 3 ],
  [ "SET 0, L", 0xc5cb, 3 ],
  [ "SET 1, A", 0xcfcb, 3 ],
  [ "SET 1, B", 0xc8cb, 3 ],
  [ "SET 1, C", 0xc9cb, 3 ],
  [ "SET 1, D", 0xcacb, 3 ],
  [ "SET 1, E", 0xcbcb, 3 ],
  [ "SET 1, H", 0xcccb, 3 ],
  [ "SET 1, [HL]", 0xcecb, 3 ],
  [ "SET 1, L", 0xcdcb, 3 ],
  [ "SET 2, A", 0xd7cb, 3 ],
  [ "SET 2, B", 0xd0cb, 3 ],
  [ "SET 2, C", 0xd1cb, 3 ],
  [ "SET 2, D", 0xd2cb, 3 ],
  [ "SET 2, E", 0xd3cb, 3 ],
  [ "SET 2, H", 0xd4cb, 3 ],
  [ "SET 2, [HL]", 0xd6cb, 3 ],
  [ "SET 2, L", 0xd5cb, 3 ],
  [ "SET 3, A", 0xdfcb, 3 ],
  [ "SET 3, B", 0xd8cb, 3 ],
  [ "SET 3, C", 0xd9cb, 3 ],
  [ "SET 3, D", 0xdacb, 3 ],
  [ "SET 3, E", 0xdbcb, 3 ],
  [ "SET 3, H", 0xdccb, 3 ],
  [ "SET 3, [HL]", 0xdecb, 3 ],
  [ "SET 3, L", 0xddcb, 3 ],
  [ "SET 4, A", 0xe7cb, 3 ],
  [ "SET 4, B", 0xe0cb, 3 ],
  [ "SET 4, C", 0xe1cb, 3 ],
  [ "SET 4, D", 0xe2cb, 3 ],
  [ "SET 4, E", 0xe3cb, 3 ],
  [ "SET 4, H", 0xe4cb, 3 ],
  [ "SET 4, [HL]", 0xe6cb, 3 ],
  [ "SET 4, L", 0xe5cb, 3 ],
  [ "SET 5, A", 0xefcb, 3 ],
  [ "SET 5, B", 0xe8cb, 3 ],
  [ "SET 5, C", 0xe9cb, 3 ],
  [ "SET 5, D", 0xeacb, 3 ],
  [ "SET 5, E", 0xebcb, 3 ],
  [ "SET 5, H", 0xeccb, 3 ],
  [ "SET 5, [HL]", 0xeecb, 3 ],
  [ "SET 5, L", 0xedcb, 3 ],
  [ "SET 6, A", 0xf7cb, 3 ],
  [ "SET 6, B", 0xf0cb, 3 ],
  [ "SET 6, C", 0xf1cb, 3 ],
  [ "SET 6, D", 0xf2cb, 3 ],
  [ "SET 6, E", 0xf3cb, 3 ],
  [ "SET 6, H", 0xf4cb, 3 ],
  [ "SET 6, [HL]", 0xf6cb, 3 ],
  [ "SET 6, L", 0xf5cb, 3 ],
  [ "SET 7, A", 0xffcb, 3 ],
  [ "SET 7, B", 0xf8cb, 3 ],
  [ "SET 7, C", 0xf9cb, 3 ],
  [ "SET 7, D", 0xfacb, 3 ],
  [ "SET 7, E", 0xfbcb, 3 ],
  [ "SET 7, H", 0xfccb, 3 ],
  [ "SET 7, [HL]", 0xfecb, 3 ],
  [ "SET 7, L", 0xfdcb, 3 ],
  [ "SLA A", 0x27cb, 3 ],
  [ "SLA B", 0x20cb, 3 ],
  [ "SLA C", 0x21cb, 3 ],
  [ "SLA D", 0x22cb, 3 ],
  [ "SLA E", 0x23cb, 3 ],
  [ "SLA H", 0x24cb, 3 ],
  [ "SLA [HL]", 0x26cb, 3 ],
  [ "SLA L", 0x25cb, 3 ],
  [ "SRA A", 0x2fcb, 3 ],
  [ "SRA B", 0x28cb, 3 ],
  [ "SRA C", 0x29cb, 3 ],
  [ "SRA D", 0x2acb, 3 ],
  [ "SRA E", 0x2bcb, 3 ],
  [ "SRA H", 0x2ccb, 3 ],
  [ "SRA [HL]", 0x2ecb, 3 ],
  [ "SRA L", 0x2dcb, 3 ],
  [ "SRL A", 0x3fcb, 3 ],
  [ "SRL B", 0x38cb, 3 ],
  [ "SRL C", 0x39cb, 3 ],
  [ "SRL D", 0x3acb, 3 ],
  [ "SRL E", 0x3bcb, 3 ],
  [ "SRL H", 0x3ccb, 3 ],
  [ "SRL [HL]", 0x3ecb, 3 ],
  [ "SRL L", 0x3dcb, 3 ],
  [ "STOP", 0x10, 0 ],
  [ "SUB A", 0x97, 0 ],
  [ "SUB B", 0x90, 0 ],
  [ "SUB C", 0x91, 0 ],
  [ "SUB D", 0x92, 0 ],
  [ "SUB E", 0x93, 0 ],
  [ "SUB H", 0x94, 0 ],
  [ "SUB [HL]", 0x96, 0 ],
  [ "SUB L", 0x95, 0 ],
  [ "SUB x", 0xd6, 1 ],
  [ "SWAP A", 0x37cb, 3 ],
  [ "SWAP B", 0x30cb, 3 ],
  [ "SWAP C", 0x31cb, 3 ],
  [ "SWAP D", 0x32cb, 3 ],
  [ "SWAP E", 0x33cb, 3 ],
  [ "SWAP H", 0x34cb, 3 ],
  [ "SWAP [HL]", 0x36cb, 3 ],
  [ "SWAP L", 0x35cb, 3 ],
  [ "XOR A", 0xaf, 0 ],
  [ "XOR B", 0xa8, 0 ],
  [ "XOR C", 0xa9, 0 ],
  [ "XOR D", 0xaa, 0 ],
  [ "XOR E", 0xab, 0 ],
  [ "XOR H", 0xac, 0 ],
  [ "XOR [HL]", 0xae, 0 ],
  [ "XOR L", 0xad, 0 ],
  [ "XOR x", 0xee, 1 ],
  [ "E", 0x100, -1 ],
]

#find conflicts
conflict_table = {}
for line in temp_opt_table:
    if line[1] in conflict_table.keys():
        print("CONFLICT: " + line[0] + " ($" + hex(line[1])[2:] + ") .... " + conflict_table[line[1]])
    else:
        conflict_table[line[1]] = line[0]

#construct real opt_table
opt_table = {}
for line in temp_opt_table:
    opt_table[line[1]] = [line[0], line[2]]
del temp_opt_table
del line

end_08_scripts_with = [
0xe9, #jp hl
#0xc3, #jp
##0x18, #jr
0xc9, #ret
###0xda, 0xe9, 0xd2, 0xc2, 0xca, 0xc3, 0x38, 0x30, 0x20, 0x28, 0x18, 0xd8, 0xd0, 0xc0, 0xc8, 0xc9
]
relative_jumps = [0x38, 0x30, 0x20, 0x28, 0x18, 0xc3, 0xda, 0xc2]
relative_unconditional_jumps = [0xc3, 0x18]

#TODO: replace call and a pointer with call and a label
call_commands = [0xdc, 0xd4, 0xc4, 0xcc, 0xcd]

all_labels = {}

def load_labels(filename="labels.json"):
    global all_labels
    if os.path.exists(filename):
        all_labels = json.loads(open(filename, "r").read())
    else:
        print("You must run analyze_incbins.scan_for_predefined_labels() to create \"labels.json\". Trying...")
        from . import analyze_incbins
        analyze_incbins.scan_for_predefined_labels()
load_labels()

def find_label(local_address, bank_id=0):
    global all_labels
    #keep an integer
    if type(local_address) == str:
        local_address1 = int(local_address.replace("$", "0x"), 16)
    else: local_address1 = local_address

    #turn local_address into a string
    if type(local_address) == str:
        if "0x" in local_address: local_address = local_address.replace("0x", "$")
        elif not "$" in local_address: local_address = "$" + local_address
    if type(local_address) == int:
        local_address = "$%.x" % (local_address)
    local_address = local_address.upper()

    for label_entry in all_labels:
        if label_entry["local_pointer"].upper() == local_address:
            if label_entry["bank_id"] == bank_id or (local_address1 < 0x8000 and (label_entry["bank_id"] == 0 or label_entry["bank_id"] == 1)):
                return label_entry["label"]
    return None

def random_asm_label():
    return ".ASM_" + random_hash()

def asm_label(address):
    # why using a random value when you can use the eff. address?
    return ".ASM_" + hex(address)[2:]

def output_bank_opcodes(original_offset, max_byte_count=0x4000):
    #fs = current_address
    #b = bank_byte
    #in = input_data  -- extract_maps.rom
    #bank_size = byte_count
    #i = offset
    #ad = end_address
    #a, oa = current_byte_number

    bank_id = 0
    if original_offset > 0x8000:
        bank_id = original_offset / 0x4000
    print("bank id is: " + str(bank_id))

    last_hl_address = None #for when we're scanning the main map script
    last_a_address = None
    used_3d97 = False

    rom = extract_maps.rom
    offset = original_offset
    current_byte_number = 0 #start from the beginning

    #we don't actually have an end address, but we'll just say $4000
    end_address = original_offset + max_byte_count

    byte_labels = {}

    output = ""
    keep_reading = True
    while offset <= end_address and keep_reading:
        current_byte = ord(extract_maps.rom[offset])
        is_data = False
        maybe_byte = current_byte

        #first check if this byte already has a label
        #if it does, use the label
        #if not, generate a new label
        if offset in byte_labels.keys():
            line_label = byte_labels[offset]["name"]
            byte_labels[offset]["usage"] += 1
        else:
            line_label = asm_label(offset)
            byte_labels[offset] = {}
            byte_labels[offset]["name"] = line_label
            byte_labels[offset]["usage"] = 0
        byte_labels[offset]["definition"] = True
        output += line_label.lower() + "\n" #" ; " + hex(offset) + "\n"

        #find out if there's a two byte key like this
        temp_maybe = maybe_byte
        temp_maybe += ( ord(rom[offset+1]) << 8)
        if temp_maybe in opt_table.keys() and ord(rom[offset+1])!=0:
            opstr = opt_table[temp_maybe][0].lower()

            if "x" in opstr:
                for x in range(0, opstr.count("x")):
                    insertion = ord(rom[offset + 1])
                    insertion = "$" + hex(insertion)[2:]

                    opstr = opstr[:opstr.find("x")].lower() + insertion + opstr[opstr.find("x")+1:].lower()

                    current_byte += 1
                    offset += 1
            if "?" in opstr:
                for y in range(0, opstr.count("?")):
                    byte1 = ord(rom[offset + 1])
                    byte2 = ord(rom[offset + 2])

                    number = byte1
                    number += byte2 << 8;

                    insertion = "$%.4x" % (number)

                    opstr = opstr[:opstr.find("?")].lower() + insertion + opstr[opstr.find("?")+1:].lower()

                    current_byte_number += 2
                    offset += 2

            output += spacing + opstr #+ " ; " + hex(offset)
            output += "\n"

            current_byte_number += 2
            offset += 2
        elif maybe_byte in opt_table.keys():
            op_code = opt_table[maybe_byte]
            op_code_type = op_code[1]
            op_code_byte = maybe_byte

            #type = -1 when it's the E op
            #if op_code_type != -1:
            if   op_code_type == 0 and ord(rom[offset]) == op_code_byte:
                op_str = op_code[0].lower()

                output += spacing + op_code[0].lower() #+ " ; " + hex(offset)
                output += "\n"

                offset += 1
                current_byte_number += 1
            elif op_code_type == 1 and ord(rom[offset]) == op_code_byte:
                oplen = len(op_code[0])
                opstr = copy(op_code[0])
                xes = op_code[0].count("x")
                include_comment = False
                for x in range(0, xes):
                    insertion = ord(rom[offset + 1])
                    insertion = "$" + hex(insertion)[2:]

                    if current_byte == 0x18 or current_byte==0x20 or current_byte in relative_jumps: #jr or jr nz
                        #generate a label for the byte we're jumping to
                        target_address = offset + 2 + c_int8(ord(rom[offset + 1])).value
                        if target_address in byte_labels.keys():
                            byte_labels[target_address]["usage"] = 1 + byte_labels[target_address]["usage"]
                            line_label2 = byte_labels[target_address]["name"]
                        else:
                            line_label2 = asm_label(target_address)
                            byte_labels[target_address] = {}
                            byte_labels[target_address]["name"] = line_label2
                            byte_labels[target_address]["usage"] = 1
                            byte_labels[target_address]["definition"] = False

                        insertion = line_label2.lower()
                        include_comment = True
                    elif current_byte == 0x3e:
                        last_a_address = ord(rom[offset + 1])

                    opstr = opstr[:opstr.find("x")].lower() + insertion + opstr[opstr.find("x")+1:].lower()
                    output += spacing + opstr
                    if include_comment:
                        output += " ; " + hex(offset)
                        if current_byte in relative_jumps:
                            output += " $" + hex(ord(rom[offset + 1]))[2:]
                    output += "\n"

                    current_byte_number += 1
                    offset += 1
                    insertion = ""

                current_byte_number += 1
                offset += 1
                include_comment = False
            elif op_code_type == 2 and ord(rom[offset]) == op_code_byte:
                oplen = len(op_code[0])
                opstr = copy(op_code[0])
                qes = op_code[0].count("?")
                for x in range(0, qes):
                    byte1 = ord(rom[offset + 1])
                    byte2 = ord(rom[offset + 2])

                    number = byte1
                    number += byte2 << 8;

                    insertion = "$%.4x" % (number)
                    if maybe_byte in call_commands or current_byte in relative_unconditional_jumps or current_byte in relative_jumps:
                        result = find_label(insertion, bank_id)
                        if result != None:
                            insertion = result

                    opstr = opstr[:opstr.find("?")].lower() + insertion + opstr[opstr.find("?")+1:].lower()
                    output += spacing + opstr #+ " ; " + hex(offset)
                    output += "\n"

                    current_byte_number += 2
                    offset += 2

                current_byte_number += 1
                offset += 1

                if current_byte == 0x21:
                    last_hl_address = byte1 + (byte2 << 8)
                if current_byte == 0xcd:
                    if number == 0x3d97: used_3d97 = True

                #duck out if this is jp $24d7
                if current_byte == 0xc3 or current_byte in relative_unconditional_jumps:
                    if current_byte == 0xc3:
                        if number == 0x3d97: used_3d97 = True
                    #if number == 0x24d7: #jp
                    if not has_outstanding_labels(byte_labels) or all_outstanding_labels_are_reverse(byte_labels, offset):
                        keep_reading = False
                        is_data = False
                        break
            else:
                is_data = True

            #stop reading at a jump, relative jump or return
            if current_byte in end_08_scripts_with:
                if not has_outstanding_labels(byte_labels) and all_outstanding_labels_are_reverse(byte_labels, offset):
                    keep_reading = False
                    is_data = False #cleanup
                    break
                else:
                    is_data = False
                    keep_reading = True
            else:
                is_data = False
                keep_reading = True
        else:
#        if is_data and keep_reading:
            output += spacing + "db $" + hex(ord(rom[offset]))[2:] #+ " ; " + hex(offset)
            output += "\n"
            offset += 1
            current_byte_number += 1
        #else the while loop would have spit out the opcode

        #these two are done prior
        #offset += 1
        #current_byte_number += 1

    #clean up unused labels
    for label_line in byte_labels.keys():
        address = label_line
        label_line = byte_labels[label_line]
        if label_line["usage"] == 0:
            output = output.replace((label_line["name"] + "\n").lower(), "")

    #add the offset of the final location
    output += "; " + hex(offset)

    return (output, offset, last_hl_address, last_a_address, used_3d97)

def has_outstanding_labels(byte_labels):
    """
    if a label is used once, it means it has to be called or specified later
    """
    for label_line in byte_labels.keys():
        real_line = byte_labels[label_line]
        if real_line["definition"] == False: return True
    return False

def all_outstanding_labels_are_reverse(byte_labels, offset):
    for label_id in byte_labels.keys():
        line = byte_labels[label_id] # label_id is also the address
        if line["definition"] == False:
            if not label_id < offset: return False
    return True

def text_asm_pretty_printer(label, address_of_08, include_08=True):
    """returns (output, end_address)"""
    output = label + ": ; " + hex(address_of_08) + "\n"
    if include_08:
        output += spacing + "db $08 ; asm\n"
        results = output_bank_opcodes(address_of_08 + 1)
    else:
        results = output_bank_opcodes(address_of_08)
    output += results[0]
    end_address = results[1]

    return (output, end_address)

if __name__ == "__main__":
    extract_maps.load_rom()
    extract_maps.load_map_pointers()
    extract_maps.read_all_map_headers()

    print(output_bank_opcodes(int(sys.argv[1], 16))[0])


import time
from pathlib import Path

import numpy as np
import torch
import torch.nn.functional as F
from torch import optim
from torch.utils.data import DataLoader

import vocoder.hparams as hp
from vocoder.display import stream, simple_table
from vocoder.distribution import discretized_mix_logistic_loss
from vocoder.gen_wavernn import gen_testset
from vocoder.models.fatchord_version import WaveRNN
from vocoder.vocoder_dataset import VocoderDataset, collate_vocoder

def train(run_id: str, syn_dir: Path, voc_dir: Path, models_dir: Path, ground_truth: bool, save_every: int,
          backup_every: int, force_restart: bool):
    # Check to make sure the hop length is correctly factorised
    assert np.cumprod(hp.voc_upsample_factors)[-1] == hp.hop_length

    # Instantiate the model
    print("Initializing the model...")
    model = WaveRNN(
        rnn_dims=hp.voc_rnn_dims,
        fc_dims=hp.voc_fc_dims,
        bits=hp.bits,
        pad=hp.voc_pad,
        upsample_factors=hp.voc_upsample_factors,
        feat_dims=hp.num_mels,
        compute_dims=hp.voc_compute_dims,
        res_out_dims=hp.voc_res_out_dims,
        res_blocks=hp.voc_res_blocks,
        hop_length=hp.hop_length,
        sample_rate=hp.sample_rate,
        mode=hp.voc_mode
    )

    if torch.cuda.is_available():
        model = model.cuda()

    # Initialize the optimizer
    optimizer = optim.Adam(model.parameters())
    for p in optimizer.param_groups:
        p["lr"] = hp.voc_lr
    loss_func = F.cross_entropy if model.mode == "RAW" else discretized_mix_logistic_loss

    # Load the weights
    model_dir = models_dir / run_id
    model_dir.mkdir(exist_ok=True)
    weights_fpath = model_dir / "vocoder.pt"
    if force_restart or not weights_fpath.exists():
        print("\nStarting the training of WaveRNN from scratch\n")
        model.save(weights_fpath, optimizer)
    else:
        print("\nLoading weights at %s" % weights_fpath)
        model.load(weights_fpath, optimizer)
        print("WaveRNN weights loaded from step %d" % model.step)

    # Initialize the dataset
    metadata_fpath = syn_dir.joinpath("train.txt") if ground_truth else \
        voc_dir.joinpath("synthesized.txt")
    mel_dir = syn_dir.joinpath("mels") if ground_truth else voc_dir.joinpath("mels_gta")
    wav_dir = syn_dir.joinpath("audio")
    dataset = VocoderDataset(metadata_fpath, mel_dir, wav_dir)
    test_loader = DataLoader(dataset, batch_size=1, shuffle=True)

    # Begin the training
    simple_table([('Batch size', hp.voc_batch_size),
                  ('LR', hp.voc_lr),
                  ('Sequence Len', hp.voc_seq_len)])

    for epoch in range(1, 350):
        data_loader = DataLoader(dataset, hp.voc_batch_size, shuffle=True, num_workers=2, collate_fn=collate_vocoder)
        start = time.time()
        running_loss = 0.

        for i, (x, y, m) in enumerate(data_loader, 1):
            if torch.cuda.is_available():
                x, m, y = x.cuda(), m.cuda(), y.cuda()

            # Forward pass
            y_hat = model(x, m)
            if model.mode == 'RAW':
                y_hat = y_hat.transpose(1, 2).unsqueeze(-1)
            elif model.mode == 'MOL':
                y = y.float()
            y = y.unsqueeze(-1)

            # Backward pass
            loss = loss_func(y_hat, y)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            running_loss += loss.item()
            speed = i / (time.time() - start)
            avg_loss = running_loss / i

            step = model.get_step()
            k = step // 1000

            if backup_every != 0 and step % backup_every == 0 :
                model.checkpoint(model_dir, optimizer)

            if save_every != 0 and step % save_every == 0 :
                model.save(weights_fpath, optimizer)

            msg = f"| Epoch: {epoch} ({i}/{len(data_loader)}) | " \
                f"Loss: {avg_loss:.4f} | {speed:.1f} " \
                f"steps/s | Step: {k}k | "
            stream(msg)

        gen_testset(model, test_loader, hp.voc_gen_at_checkpoint, hp.voc_gen_batched,
                    hp.voc_target, hp.voc_overlap, model_dir)
        print("")


try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup
import sys

from codecs import open
from os import path

if sys.version < '3.5.1':
    print("Supports only Python >= 3.5.1")
    sys.exit(1)

this_directory = path.abspath(path.dirname(__file__))
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
    long_description = f.read()

setup(
    name='chef-cli',
    include_package_data=True,
    packages=["chefcli"],
    data_files=[('chefcli', [])],
    entry_points={'console_scripts': ['chef-cli = chefcli.__main__:main']},
    install_requires=['python-decouple', 'mdv',
                      'requests', 'termgraph', 'termcolor'],
    python_requires='>=3.5',
    requires=['decouple', 'mdv', 'requests', 'termgraph', 'termcolor'],
    version='1.0.1',
    url='https://github.com/mkfeuhrer/chef-cli',
    keywords="chef-cli codechef cli programming",
    license='MIT',
    author='Abhey Rana',
    author_email='abhey.mnnit@gmail.com',
    description='CodeChef command line interface. ChefCLI helps competitive coders to search, view,\
                 and submit problems in CodeChef.',
    long_description=long_description,
    long_description_content_type='text/markdown'
)


"""Evaluate the model"""

import argparse
import logging
import os

import tensorflow as tf

from model.input_fn import input_fn
from model.model_fn import model_fn
from model.evaluation import evaluate
from model.utils import Params
from model.utils import set_logger

n_zeros = 1 # should be same to train n_zeros

parser = argparse.ArgumentParser()
parser.add_argument('--model_dir', default='C:\\Users\\DamonChang\\Desktop\\KETI_pose\\edm2d\\experiments\\base_model')
parser.add_argument('--data_dir', default='D:\\Human pose DB\\data\\img')
parser.add_argument('--restore_from', default='best_weights')

if __name__ == '__main__':
    # Set the random seed for the whole graph
    tf.set_random_seed(230)

    # Load the parameters
    args = parser.parse_args()
    json_path = os.path.join(args.model_dir, 'params.json')
    assert os.path.isfile(json_path), "No json configuration file found at {}".format(json_path)
    params = Params(json_path)

    # Set the logger
    set_logger(os.path.join(args.model_dir, 'evaluate.log'))

    # Create the input data pipeline
    logging.info("Creating the datasets...")
    data_dir = args.data_dir
    test_data_dir = os.path.join(data_dir, 'zeros_{}'.format(n_zeros), 'tt')

    # Get the filenames from the test set

    test_filenames = [os.path.join(test_data_dir, 'img', f) for f in os.listdir(test_data_dir + '\\' + 'img')[:200]]
    test_labels = [os.path.join(test_data_dir, 'label', f) for f in os.listdir(test_data_dir + '\\' + 'label')[:200]]

    # specify the size of the evaluation set
    params.eval_size = len(test_filenames)

    # create the iterator over the dataset
    test_inputs = input_fn(False, test_filenames, test_labels, params)

    # Define the model
    logging.info("Creating the model...")
    model_spec = model_fn('eval', test_inputs, params, reuse=False)

    logging.info("Starting evaluation")
    evaluate(model_spec, args.model_dir, params, args.restore_from)


# Utils

import glob
import numpy as np
import seaborn as sns
import collections
import matplotlib.pyplot as plt

PDB_TO_UNIPROT_TABLE_PATH = "/scratch/PI/rondror/akma327/DynamicNetworks/data/crystal-analysis/simulation-analysis/gpcrdb-freq-config/GPCR_PDB_List.txt"
GPCRDB_TABLE_PATH="/scratch/PI/rondror/akma327/DynamicNetworks/data/crystal-analysis/simulation-analysis/gpcrdb-freq-config/All_species_gpcrdb_numbers_strOnly.txt"

# Rename amino acids to common name
def fixAminoAcidNames(key):
	key = key.replace("HSD", "HIS")
	key = key.replace("HSE", "HIS")
	key = key.replace("HSP", "HIS")
	key = key.replace("HIE", "HIS")
	key = key.replace("HIP", "HIS")
	key = key.replace("HID", "HIS")
	key = key.replace("GLH", "GLU")
	key = key.replace("ASH", "ASP")
	key = key.replace("CYP", "CYS")
	key = key.replace("CYX", "CYS")
	return key

def getGPCRDB(res, GPCRDB_DICT):
	res = fixAminoAcidNames(res)
	if(res == "LIG"): return "LIGxLIG"
	if(res not in GPCRDB_DICT):
# 		print(res + " not found.")
		return "None"
	return GPCRDB_DICT[res]

# Retrieve Uniprot Code for the PDB_CODE from pdb_to_uniprot_table_path
def getUniprotCode(PDB_CODE):
	f = open(PDB_TO_UNIPROT_TABLE_PATH, 'r')
	for line in f:
		if(line == "\n"): continue
		l_info = line.split("\t")
		uniprot_code, pdb = l_info[0].strip(), l_info[2].strip()
		if(PDB_CODE.upper() == pdb.upper()): return uniprot_code.upper()
	print("PDB_CODE Not Found in PDB To Uniprot Table")
	exit(1)

# Given uniprot code reads through GPCRDB_TABLE_PATH to generate the amino acid
# to gpcrdb number table.
# Output {"ASP112": "1x50", "ARG116":"2x45"}
def genGpcrdbDict(UNIPROT_CODE):
	GPCRDB_DICT = {}
	f = open(GPCRDB_TABLE_PATH, 'r')
	for line in f:
		l_info = line.split("\t")
		uniprot, resnum, resname, gpcrdb = l_info[0].strip(), l_info[1].strip(), l_info[2].strip(), l_info[4].strip()
		if(uniprot.upper() == UNIPROT_CODE.upper()):
			key = resname.upper() + resnum
			GPCRDB_DICT[key] = gpcrdb
	return GPCRDB_DICT

# Generates the residue to gpcrdb table for given pdb
def genResidueToGpcrdbTable(PDB_CODE):
	UNIPROT_CODE = getUniprotCode(PDB_CODE)
	GPCRDB_DICT = genGpcrdbDict(UNIPROT_CODE)
	return GPCRDB_DICT

POSITION_CONSERVATION_PATH="/scratch/PI/rondror/akma327/DynamicNetworks/data/crystal-analysis/simulation-analysis/gpcrdb-freq-config/gpcrdb_residue_conservation.txt"

def position_to_conserve_freq():
	f = open(POSITION_CONSERVATION_PATH, 'r')
	header = f.readline()
	pos_to_conserve_freq = {}
	for line in f:
		linfo = line.strip().split("\t")
		position = linfo[0]
		max_conserve_freq = max(map(float, linfo[1:]))
		pos_to_conserve_freq[position] = max_conserve_freq

	return pos_to_conserve_freq

def get_sorted_positions(positions):
	aa_freq = position_to_conserve_freq()
	pos_to_aa_freq = Counter()
	for pos in positions:
		freq = aa_freq[pos]
		pos_to_aa_freq[pos] = freq

	sorted_pos = [pos for pos, freq in pos_to_aa_freq.most_common()]
	return sorted_pos


import importlib
import subprocess
import sys

import pytest

_PMGEN_PY_DIRPATH_DEFAULT = ".."
_PMGEN_PY_FNAME_DEFAULT = "pmgen.py"

_PMGEN_DIRNAME_DEFAULT = "pmgen"
_COMPILED_MOD_FNAME_SUFFIX = ".so"
_NIM_MOD_FNAME_SUFFIX = ".nim"
_RENAME_PREFIX_FOR_FAILED_TEST = "failed_"

##
## Add extra information to the test report header.
##

def pytest_report_header(config):
    # https://pytest.org/latest/example/simple.html#adding-info-to-test-report-header

    nim_version_output = subprocess.check_output(["nim", "--version"], stderr=subprocess.STDOUT)
    if sys.version_info.major >= 3:
        # Python 3: `lines` has type `bytes`.
        lines = nim_version_output.split(b"\n")
    else:
        # Python 2: `lines` has type `str`.
        lines = nim_version_output.split("\n")
    return lines[0]

##
## Configure the command-line parser.
##

def pytest_addoption(parser):
    """Add custom command-line options to the command-line parser."""
    # http://pytest.readthedocs.org/en/2.0.3/plugins.html#_pytest.hookspec.pytest_addoption

    # Pytest's option parser is similar to Python's stdlib `argparse`:
    #  https://docs.python.org/2/library/argparse.html#argparse.ArgumentParser.add_argument
    pmgen_py_dirpath_help = \
            "override the directory path to the 'pmgen.py' script " + \
            "from the default of '%(default)s'. The path can be specified " + \
            "as a relative path or absolute path."
    parser.addoption("--pmgen_py_dirpath", type="string", metavar="DIRPATH",
            default=_PMGEN_PY_DIRPATH_DEFAULT, action="store", dest="pmgen_py_dirpath",
            help=pmgen_py_dirpath_help)

    pmgen_py_fname_help = \
            "override the filename of the 'pmgen.py' script " + \
            "from the default of '%(default)s'."
    parser.addoption("--pmgen_py_fname", type="string", metavar="FNAME",
            default=_PMGEN_PY_FNAME_DEFAULT, action="store", dest="pmgen_py_fname",
            help=pmgen_py_fname_help)

##
## Utility functions
##

def _get_option_value(config, option_name, option_default_value):
    cmdline_option_value = config.getoption(option_name)
    if cmdline_option_value and (cmdline_option_value != option_default_value):
        return cmdline_option_value

    inicfg_option_value = config.inicfg.get(option_name)
    if inicfg_option_value and (inicfg_option_value != option_default_value):
        return inicfg_option_value

    return option_default_value

def _localpath_exists(localpath):
    return (localpath.stat(raising=False) is not None)

def _get_test_dir_that_contains_module(request):
    # Note that `request.fspath` returns a LocalPath instance, not a string.
    #  http://py.readthedocs.org/en/latest/path.html#py._path.local.LocalPath
    #
    # But, dumb API design: `.dirname` returns `str` rather than `LocalPath`.
    # So we have to use `.parts(reverse=True)[1]` instead.
    #test_dir = request.fspath.dirname
    test_dir = request.fspath.parts(reverse=True)[1]
    return test_dir

def _get_pymod_test_mod_name(request):
    return "_%s" % request.module.__name__

def _get_pymod_test_mod_fname(request):
    return "_%s%s" % (request.module.__name__, _COMPILED_MOD_FNAME_SUFFIX)

##
## Session fixtures
##

@pytest.fixture(scope="session")
def pmgen_py_fullpath(request):
    """Return the correct fullpath of the "pmgen.py" script for this session.
    This checks for user-specified values in the "pytest.ini" file & in the
    command-line options.  It will double-check that the specified fullpath
    actually exists.
    """
    pmgen_py_dirpath = _get_option_value(request.config, "pmgen_py_dirpath", _PMGEN_PY_DIRPATH_DEFAULT)
    pmgen_py_fname = _get_option_value(request.config, "pmgen_py_fname", _PMGEN_PY_FNAME_DEFAULT)
    print("\nInitializing test session...")
    print(" - pmgen.py dirpath specified: %s" % pmgen_py_dirpath)
    print(" - pmgen.py fname specified: %s" % pmgen_py_fname)

    # Note that `request.config.invocation_dir` returns a LocalPath instance,
    # not a string.
    #  http://py.readthedocs.org/en/latest/path.html#py._path.local.LocalPath
    invocation_dir = request.config.invocation_dir
    pmgen_py_fullpath = invocation_dir.join(pmgen_py_dirpath, pmgen_py_fname, abs=1)
    print(" > pmgen.py fullpath to use: %s\n" % pmgen_py_fullpath)

    # Ensure the specified fullpath actually exists.
    if not _localpath_exists(pmgen_py_fullpath):
        request.raiseerror("file does not exist: %s" % pmgen_py_fullpath)

    return str(pmgen_py_fullpath)

@pytest.fixture(scope="session")
def python_exe_fullpath(request):
    """Return the fullpath of the Python executable to run for this session.
    This also tells us the version of Python (ie, 2 or 3) that is being used.
    """
    # https://docs.python.org/2/library/sys.html#sys.executable
    python_exe_path = sys.executable
    if not python_exe_path:
        # "If Python is unable to retrieve the real path to its executable,
        # `sys.executable` will be an empty string or None."
        request.raiseerror("unable to determine real path to Python executable")

    return python_exe_path

@pytest.fixture(scope="session")
def python_major_version(request):
    """Return the (int) major version of Python being used for this session."""
    # https://docs.python.org/2/library/sys.html#sys.version_info
    return sys.version_info.major

##
## Module fixtures
##

@pytest.fixture(scope="module", autouse=True)
def chdir_into_test_dir(request):
    """Change directory into the correct test directory for this module.
    This also sets a finalizer that will change back to the previous directory
    when the tests in this module are complete (or have failed).  If the tests
    in this module have all passed, the finalizer will also clean up any files
    or subdirectories that were created by Pymod in this test directory.
    """
    print("\nInitializing test module: %s" % request.module.__name__)

    # Note that `request.config.invocation_dir` returns a LocalPath instance,
    # not a string.
    #  http://py.readthedocs.org/en/latest/path.html#py._path.local.LocalPath
    invocation_dir = request.config.invocation_dir
    print("Pytest invocation directory: %s" % invocation_dir)

    test_dir = _get_test_dir_that_contains_module(request)
    print("Chdir into test directory: %s" % test_dir)
    prev_dir = test_dir.chdir()

    def chdir_back_to_starting_dir():
        # Test whether there are any files we should delete before we leave.
        pymod_test_mod_fullpath = test_dir.join(_get_pymod_test_mod_fname(request))
        if _localpath_exists(pymod_test_mod_fullpath):
            print("\nDelete file: %s" % pymod_test_mod_fullpath)
            pymod_test_mod_fullpath.remove()

        pmgen_dir_fullpath = test_dir.join(_PMGEN_DIRNAME_DEFAULT)
        if _localpath_exists(pmgen_dir_fullpath):
            print("Delete directory: %s" % pmgen_dir_fullpath)
            pmgen_dir_fullpath.remove(rec=1, ignore_errors=True)

        print("\nChdir back to previous directory: %s" % prev_dir)
        prev_dir.chdir()
    request.addfinalizer(chdir_back_to_starting_dir)

##
## Function fixtures
##

# This function is copy-pasted from the example of how to
# "[make] test result information available in fixtures" at:
#  https://pytest.org/latest/example/simple.html#making-test-result-information-available-in-fixtures
# and:
#  https://github.com/pytest-dev/pytest/issues/288
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    # Execute all other hooks to obtain the report object.
    outcome = yield
    rep = outcome.get_result()

    # Set an report attribute for each phase of a call, which can be
    # "setup", "call", "teardown".
    setattr(item, "rep_" + rep.when, rep)

# This function is based upon the example of how to
# "[make] test result information available in fixtures" at:
#  https://pytest.org/latest/example/simple.html#making-test-result-information-available-in-fixtures
# and:
#  https://github.com/pytest-dev/pytest/issues/288
#
# This fixture relies upon setup performed by hook `pytest_runtest_makereport`.
@pytest.fixture(autouse=True)
def act_upon_test_result(request):
    """Set a finalizer that will act upon the result of test success/failure."""
    test_dir = _get_test_dir_that_contains_module(request)
    def fin():
        # Because this is a function-scope fixture, `request.node` corresponds
        # to a single test function.
        if request.node.rep_setup.failed:
            print("Test setup failed: %s" % request.node.nodeid)
            pass
        elif request.node.rep_setup.passed:
            if request.node.rep_call.failed:
                print("\n\nTest failed: %s\nPreserving temporary files for review..." %
                        request.node.nodeid)

                pymod_test_mod_fname = _get_pymod_test_mod_fname(request)
                pymod_test_mod_fullpath = test_dir.join(pymod_test_mod_fname)
                if _localpath_exists(pymod_test_mod_fullpath):
                    failed_fname = _RENAME_PREFIX_FOR_FAILED_TEST + pymod_test_mod_fname
                    pymod_test_mod_failed_fullpath = test_dir.join(failed_fname)
                    print("Rename file: %s -> %s" %
                            (pymod_test_mod_fullpath, pymod_test_mod_failed_fullpath))
                    pymod_test_mod_fullpath.rename(pymod_test_mod_failed_fullpath)

                pmgen_dir_fullpath = test_dir.join(_PMGEN_DIRNAME_DEFAULT)
                if _localpath_exists(pmgen_dir_fullpath):
                    failed_fname = _RENAME_PREFIX_FOR_FAILED_TEST + _PMGEN_DIRNAME_DEFAULT
                    pmgen_dir_failed_fullpath = test_dir.join(failed_fname)
                    print("Rename directory: %s -> %s" %
                            (pmgen_dir_fullpath, pmgen_dir_failed_fullpath))
                    pmgen_dir_fullpath.rename(pmgen_dir_failed_fullpath)

    request.addfinalizer(fin)

@pytest.fixture
def pmgen_py_compile(python_exe_fullpath, pmgen_py_fullpath, request):
    """Return a closure that can be invoked to compile a Pymod Nim module."""
    def compile_py_mod(py_mod_name):
        nim_mod_fname = py_mod_name + _NIM_MOD_FNAME_SUFFIX
        subprocess.check_call([python_exe_fullpath, pmgen_py_fullpath, nim_mod_fname])
    return compile_py_mod

@pytest.fixture
def pymod_test_mod(request):
    """Import & return the Pymod test module that has been compiled."""
    return importlib.import_module(_get_pymod_test_mod_name(request))


from test_framework import generic_test
import sys

import pdb
def find_closest_elements_in_sorted_arrays(sorted_arrays):
    # TODO - you fill in here.
    pdb.set_trace()

    min_diff = float('inf')
    chosen_set = []

    idx = [0] * len(sorted_arrays)

    while True:
        vals = list(s[idx[x]] for x, s in enumerate(sorted_arrays))
        min_val, max_val = min(vals), max(vals)

        #min_diff = min(max_val-min_val, min_diff)
        if min_diff > max_val-min_val:
            min_diff = max_val-min_val
            chosen_set = vals

        min_idx = 0
        for val in vals:
            if min_val == val:
                break
            min_idx += 1

        idx[min_idx] += 1
        if idx[min_idx] == len(sorted_arrays[min_idx]):
            break

    print(chosen_set)
    return min_diff

# Pythonic using sortedcontainers - DOES NOT WORK because iters[] may have duplicate
# values. So idx has to be part of the key
from sortedcontainers import SortedDict
def find_closest_elements_in_sorted_arrays(sorted_arrays):
    # TODO - you fill in here.

    min_diff = float('inf')

    chosen_set = []
    iters = SortedDict()

    for idx, s in enumerate(sorted_arrays):
        it = iter(s)
        first_min = next(it, None)
        assert first_min is not None, pdb.set_trace()
        if first_min is not None:
            iters[first_min] = (idx, it)

    while True:
        max_val = iters.keys()[-1]
        min_val, (min_idx, it) = iters.peekitem(0)

        if min_diff > max_val-min_val:
            min_diff = max_val-min_val
            chosen_set = sorted(list((v, i) for v, (i, _) in iters.items()), key=lambda x: x[1])
        iters.popitem(0)
        next_min = next(it, None)
        if next_min == None:
            print(chosen_set)
            return min_diff
        iters[next_min] = (min_idx, it)
        assert len(iters) == len(sorted_arrays), pdb.set_trace()

from sortedcontainers import SortedDict
def find_closest_elements_in_sorted_arrays(sorted_arrays):
    # TODO - you fill in here.

    min_diff = float('inf')

    iters = SortedDict()
    chosen_set = None

    for idx, s in enumerate(sorted_arrays):
        it = iter(s)
        first_min = next(it, None)
        if first_min is not None:
            iters[(first_min, idx)] = it

    while True:
        max_val = iters.keys()[-1][0]
        min_val, min_idx = iters.keys()[0]

        if min_diff > max_val-min_val:
            min_diff = max_val-min_val
            chosen_set = sorted(list(iters.keys()), key=lambda x: x[1])
        it = iters.popitem(0)[1]

        next_min = next(it, None)
        if next_min == None:
            print(chosen_set)
            return min_diff
        iters[(next_min, min_idx)] = it
        assert len(iters) == len(sorted_arrays), pdb.set_trace()

from sortedcontainers import SortedList
def find_closest_elements_in_sorted_arrays(sorted_arrays):
    nums = sorted_arrays
    tree = SortedList()
    for i in range(len(nums)):
        tree.add((nums[i][0], i, 0))

    min_val = float('-inf')
    max_val = float('inf')
    while True:
        min, mini, i = tree[0]
        max, _, _ = tree[-1]
        if max_val - min_val > max-min:
            min_val = min
            max_val = max
        tree.pop(0)
        if i+1 < len(nums[mini]):
            tree.add((nums[mini][i+1], mini, i+1))
        else:
            break
    return max_val - min_val

if __name__ == '__main__':
    exit(
        generic_test.generic_test_main("minimum_distance_3_sorted_arrays.py",
                                       'minimum_distance_3_sorted_arrays.tsv',
                                       find_closest_elements_in_sorted_arrays))


from torchvision.utils import make_grid
import numpy as np
import imageio

def create_grid_image(images, nimage_row: int = 10,  save = False, path_to_save = 'grid_image.png') -> np.ndarray:
    '''Create one single grid images comprised of the batch of images

    Parameters
    ----------
    - images (tensor): size B x C x H x W
    - show (bool): default is False to not show created grid image.
        otherwise, show image.
    - nimage_row (int): number of images per row
    - path_to_save (str): path to save the grid image.

    Return
    ------
    - (ndarray): one single image size H x W x C
    '''
    img_grid = make_grid(images, nrow=nimage_row)
    img_grid = 255. * np.transpose(img_grid.detach().cpu().numpy(),(1,2,0))
    img_grid = img_grid.astype(np.uint8)
    if save:
        imageio.imwrite(path_to_save, img_grid)
    return img_grid

def save_gif(path, training_grid_images) -> None:
    '''Save generated grid images to a gif file.

    Parameters
    ----------
    - path (str): path to save file gif.
    - training_grid_images (list): list of gird images.
        gird image (ndarray): H x W x C, type: uint8
    '''
    imageio.mimsave(path, training_grid_images)


#!/usr/bin/env python

import os
import datetime
from pprint import pprint
import json
import logging

from icinga2api.client import Client as Icinga2Client

icinga2api = Icinga2Client(config_file='icinga2-api.ini')

CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))

logger = logging.getLogger('autoack')

def get_downtime(filters, filter_vars, object_type='Host'):
    """Lookup downtime by filters. Returns active downtime
       with the farthest end time"""
    assert object_type in ['Service', 'Host']
    downtimes = icinga2api.objects.list(
        'Downtime',
        filters=filters, filter_vars=filter_vars)

    expires_at = 0
    the_downtime = None
    for d in downtimes:
        # skip service downtimes when lookup up for host ones
        if object_type == 'Host' and 'service_name' in d['attrs']:
            continue
        # skip inactive and floating downtimes
        if not d['attrs']['active']:
            continue
        if not d['attrs']['fixed']:
            continue
        if expires_at < d['attrs']['end_time']:
            expires_at = d['attrs']['end_time']
            the_downtime = d

    return the_downtime

def acknowledge_on_downtime(the_downtime, object_type, filters, filter_vars):
    expires_at = the_downtime['attrs']['end_time']
    downtime_id = int(the_downtime['attrs']['legacy_id'])
    logger.info("Found downtime {downtime_id}, doing ACK.".format(
        downtime_id=downtime_id))
    comment = 'This is auto acknowledge. {object_type} is in downtime #{downtime_id}'.format(
        downtime_id=downtime_id, object_type=object_type,
    )
    icinga2api.actions.acknowledge_problem(
        object_type=object_type,
        filters=filters,
        filter_vars=filter_vars,
        author='AutoAck bot',
        comment=comment,
        sticky=False,
        notify=False,
        expiry=expires_at,
    )

def acknowledge_unconditionally(object_type, filters, filter_vars):
    logger.info("Doing autoack")
    comment = 'This is auto acknowledge. {object_type} has autoack attribute set'.format(
        object_type=object_type,
    )
    icinga2api.actions.acknowledge_problem(
        object_type=object_type,
        filters=filters,
        filter_vars=filter_vars,
        author='AutoAck bot',
        comment=comment,
        sticky=False,
        notify=False
    )

def has_autoack(object_type, object_name):
    data = icinga2api.objects.get(object_type=object_type, name=object_name)
    try:
        autoack = data['attrs']['vars']['autoack']
    except KeyError:
        return False
    if autoack:
        return True
    return False

def handle_stream():
    logger.info("Starting")
    for event in icinga2api.events.subscribe(
            types=['StateChange', 'DowntimeStarted', 'DowntimeTriggered'],
            queue='auto-ack'):

        if type(event) is bytes:
            event = str(event, encoding='utf-8')
        event = json.loads(event)
        pprint(event)

        host_name = event['host']
        try:
            service_name = event['service']
        except KeyError:
            service_name = None
        logger.info("Got change state event {event}".format(event=event))
        if event['state'] == 0:  # the service is up now
            continue

        if not service_name:
            object_type = 'Host'
            object_name = host_name
            filters = 'match(host.name,filter_host)'
            filter_vars = dict(filter_host=host_name)

        else:
            object_type = 'Service'
            object_name = '!'.join([host_name, service_name])
            filters = 'match(host.name,filter_host) && match(service.name,filter_service)',
            filter_vars = dict(filter_host=host_name,
                               filter_service=service_name)
        #
        the_downtime = get_downtime(object_type=object_type,
                                    filters=filters, filter_vars=filter_vars)

        if the_downtime:
            acknowledge_on_downtime(the_downtime=the_downtime,
                                    object_type=object_type,
                                    filters=filters, filter_vars=filter_vars)
            continue

        autoack_enabled = has_autoack(object_type=object_type,
                                      object_name=object_name)

        if autoack_enabled:
            acknowledge_unconditionally(object_type=object_type,
                                        filters=filters,
                                        filter_vars=filter_vars)
            continue

        if not the_downtime:
            logger.info("No active downtimes found")
            continue

if __name__ == '__main__':
    # logging.basicConfig(level=logging.DEBUG)
    logging.basicConfig(level=logging.INFO)
    handle_stream()


import boto3
from requests.models import Response
from requests_oauthlib import OAuth1Session

class TwitterClient:
    def __init__(self):
        self._ssm = boto3.client('ssm')

        twitter_consumer_key = self.get_parameter('twitter_consumer_key')
        twitter_consumer_secret = self.get_parameter('twitter_consumer_secret')
        twitter_access_token = self.get_parameter('twitter_access_token')
        twitter_access_token_secret = self.get_parameter('twitter_access_token_secret')

        self._client = OAuth1Session(
            twitter_consumer_key,
            twitter_consumer_secret,
            twitter_access_token,
            twitter_access_token_secret,
        )

    def send(self, message: str) -> Response:
        """
        Send message to Twitter
        """
        url = 'https://api.twitter.com/2/tweets'
        return self._client.post(url, json={
            'text': message,
        })

    def get_parameter(self, key: str) -> str:
        """
        Get value from Parameter Store
        """
        response = self._ssm.get_parameter(
            Name=key,
            WithDecryption=True
        )
        return response['Parameter']['Value']


import random

def jogar():
    print("************************************************")
    print("****************[ Iniciando...  ]***************")
    print("************************************************")
    numero = random.randrange(1, 100, 1)

    acertou = False
    totalDeTentativas = 5
    tentativa = 0

    print("Estou pensando número de 1 a 100\n\n")
    print("Você tem {} tentativas:".format(totalDeTentativas))
    print('---> estou pensando em: {} <---'.format(numero))

    chute = int(input('Tente adivinhar o número em que estou pensando:\n'))

    for rodada in range(1, totalDeTentativas,1):
        if(chute < 1 or chute > 100):
            rodada-=1
            chute = int(input('Você deve digitar um número entre 1 e 100: '))
            continue
        if(chute > numero):
            tentativa += 1
            print("{} é MAIOR que o número que estou pensando\nVocê ainda tem {} tentativas".format(chute, totalDeTentativas-tentativa))
            chute = int(input('Tente novamente:'))
        if(chute < numero):
            tentativa += 1
            print("{} é MENOR que o número que estou pensando\nVocê ainda tem {} tentativas".format(chute, totalDeTentativas-tentativa))
            chute = int(input('Tente novamente:'))
        if(chute == numero):
            acertou = True
            print('Você acertou, o número que eu pensei é', numero)
            break

    if(acertou == False):
        print('Você perdeu :(')
        print('O número que eu pensei foi:', numero)

    print("*************************************************")
    print("******************[ GAME OVER ]******************")
    print("*************************************************")

if(__name__ == '__main__'):
    jogar()


import torch
import torch.nn as nn
from dl_toolbox.lightning_modules import BaseModule
import dl_toolbox.augmentations as aug
from dl_toolbox.utils import TorchOneHot
from dl_toolbox.callbacks import log_batch_images

class CE(BaseModule):

    def __init__(self,
                 network,
                 weights,
                 mixup=0.,
                 ignore_index=-1,
                 *args,
                 **kwargs):

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

        net_cls = self.net_factory.create(network)
        self.network = net_cls(*args, **kwargs)
        self.num_classes = self.network.out_channels
        out_dim = self.network.out_dim
        self.weights = list(weights) if len(weights)>0 else [1]*self.num_classes
        self.ignore_index = ignore_index
        self.loss = nn.CrossEntropyLoss(
            ignore_index=self.ignore_index,
            weight=torch.Tensor(self.weights)
            #weight=torch.Tensor(self.weights).reshape(1,-1,*out_dim)
        )
        self.onehot = TorchOneHot(
            range(self.num_classes)
        )
        self.mixup = aug.Mixup(alpha=mixup) if mixup > 0. else None
        #self.save_hyperparameters('network', 'weights', 'mixup', 'ignore_index')
        self.save_hyperparameters()

    @classmethod
    def add_model_specific_args(cls, parent_parser):

        parser = super().add_model_specific_args(parent_parser)
        parser.add_argument("--ignore_index", type=int, default=-1)
        parser.add_argument("--network", type=str)
        parser.add_argument("--weights", type=float, nargs="+", default=())
        parser.add_argument("--mixup", type=float, default=0.)

        return parser

    def forward(self, x):

        return self.network(x)

    @classmethod
    def _compute_probas(cls, logits):

        return logits.softmax(dim=1)

    @classmethod
    def _compute_conf_preds(cls, probas):

        return torch.max(probas, dim=1)

    def training_step(self, batch, batch_idx):

        batch = batch["sup"]
        inputs = batch['image']
        labels = batch['mask']
        if self.mixup:
            labels = self.onehot(labels).float()
            inputs, labels = self.mixup(inputs, labels)
            #batch['image'] = inputs
        logits = self.network(inputs)
        loss = self.loss(logits, labels)
        self.log('Train_sup_CE', loss)
        batch['logits'] = logits.detach()

        if self.trainer.current_epoch % 10 == 0 and batch_idx == 0:
            log_batch_images(
                batch,
                self.trainer,
                prefix='Train'
            )

        return {'batch': batch, "loss": loss}

    def validation_step(self, batch, batch_idx):

        outs = super().validation_step(batch, batch_idx)
        labels = batch['mask']
        logits = outs['logits']
        loss = self.loss(logits, labels)
        self.log('Val_CE', loss)

        return outs


import numpy as np
import os
import sys
import argparse
import pdb
import cv2

# Borrowed from https://github.com/nficano/pytube
from pytube import YouTube

def get_parser():
    parser = argparse.ArgumentParser(description='The script to download and save the videos from Youtube')
    parser.add_argument('--csvpath', default = '/mnt/fs1/Dataset/kinetics/kinetics_train.csv', type = str, action = 'store', help = 'Path to the csv containing the information')
    parser.add_argument('--savedir', default = '/mnt/fs1/Dataset/kinetics/vd_dwnld', type = str, action = 'store', help = 'Directory to hold the downloaded videos')
    parser.add_argument('--minresz', default = 256, type = int, action = 'store', help = 'Size for the smallest edge to be resized to')
    parser.add_argument('--sta_idx', default = 0, type = int, action = 'store', help = 'Start index for downloading')
    parser.add_argument('--len_idx', default = 2500, type = int, action = 'store', help = 'Length of index of downloading')
    parser.add_argument('--check', default = 0, type = int, action = 'store', help = 'Whether checking the existence')

    return parser

def load_csv(csvpath):
    fin = open(csvpath, 'r')
    csv_lines = fin.readlines()
    csv_lines = csv_lines[1:]
    all_data = []

    cate_list = []

    curr_indx = 0

    for curr_line in csv_lines:
        if curr_line[-1]=='\n':
            curr_line = curr_line[:-1]
        line_split = curr_line.split(',')
        curr_dict = {'cate': line_split[0], 'id': line_split[1], 'sta': int(line_split[2]), 'end': int(line_split[3]), 'train': line_split[4], 'flag': int(line_split[5]), 'indx': curr_indx}

        if not curr_dict['cate'] in cate_list:
            cate_list.append(curr_dict['cate'])

        curr_dict['cate_lbl'] = cate_list.index(curr_dict['cate'])

        all_data.append(curr_dict)
        curr_indx = curr_indx + 1

    return all_data

def main():
    parser = get_parser()

    args = parser.parse_args()

    os.system('mkdir -p %s' % args.savedir)

    csv_data = load_csv(args.csvpath)

    youtube_frmt = "http://youtu.be/%s"
    #for curr_indx, curr_data in enumerate(csv_data):
    #    assert curr_data['end'] - curr_data['sta'] == 10, "Length not 10!"

    curr_len = min(len(csv_data) - args.sta_idx, args.len_idx)

    for curr_indx in xrange(args.sta_idx, args.sta_idx + curr_len):
        curr_data = csv_data[curr_indx]
        curr_youtube_web = youtube_frmt % curr_data['id']
        try:
            yt = YouTube(curr_youtube_web)
        except:
            print('Not able to open!')
            continue
        curr_fname = 'vd_%i' % curr_indx

        avi_path = os.path.join(args.savedir, '%s_mini.avi' % curr_fname)
        print(avi_path)
        if os.path.exists(avi_path):
            if args.check==0:
                os.system('rm %s' % avi_path)
            else:
                continue

        yt.set_filename(curr_fname)
        #print(yt.get_videos())
        video = yt.get('mp4', '360p')

        mp4_path = os.path.join(args.savedir, '%s.mp4' % curr_fname)
        if os.path.exists(mp4_path):
            os.system('rm %s' % mp4_path)
        video.download(args.savedir)
        vidcap = cv2.VideoCapture(mp4_path)

        fps = vidcap.get(cv2.cv.CV_CAP_PROP_FPS)
        start_indx = curr_data['sta'] * fps
        len_frame = (curr_data['end'] - curr_data['sta']) * fps
        vid_len = vidcap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)
        #print(vid_len)
        #print(start_indx)
        #print(len_frame)
        len_frame = int(min(vid_len - start_indx, len_frame))

        vid_height = vidcap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)
        vid_width = vidcap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)

        if vid_width < vid_height:
            vid_height = int(vid_height*1.0/vid_width*args.minresz)
            vid_width = 256
        else:
            vid_width = int(vid_width*1.0/vid_height*args.minresz)
            vid_height = 256

        fourcc = cv2.cv.CV_FOURCC(*'MP4V')
        vidwrt = cv2.VideoWriter(avi_path, fourcc, fps, (vid_width, vid_height))
        vidcap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, int(start_indx))

        #test_dir = os.path.join(args.savedir, 'vd_0')
        #os.system('mkdir -p %s' % test_dir)

        for indx_frame in xrange(len_frame):
            suc, frame = vidcap.read()
            #print(suc, indx_frame, len_frame)
            if not suc:
                #print(frame.shape)
                break
            frame_rsz = cv2.resize(frame, (vid_width, vid_height))
            vidwrt.write(frame_rsz)
            #cv2.imwrite(os.path.join(test_dir, 'im_%i.jpg' % indx_frame), frame_rsz)

        vidwrt.release()
        vidcap.release()

        os.system('rm %s' % mp4_path)

        if curr_indx%20==0:
            print(curr_indx)

if __name__ == '__main__':
    main()


#!/usr/bin/env python3

### Advent of Code - 2022 - Day 9

import sys, requests, re, math, itertools, functools, os, collections
from functools import lru_cache

sys.path.append('../../python/')
from aoc_utils import *

# read input data file as one long string and as an array of lines
inputfile = 'input' if len(sys.argv) < 2 else sys.argv[1]
if not os.path.exists(inputfile):
    print(RED+f"Input file {inputfile} not found!"+CLEAR)
    quit()
finput = open(inputfile,'r').read().rstrip()
input_lines = [line.strip() for line in finput.split('\n')]
print(DBLUE+f"Input <{inputfile}>, num lines: {len(input_lines)}"+CLEAR)

'''
The lead knot can be in several locations, after moving, from the next knot.

The simple case is when it's at most 1 length away:

 . . . . .
 . h h h .
 . h t h .
 . h h h .
 . . . . .

If the leading knot moves to any of those positions, we're good! Check the rest.

The other possibilities are:

 . h H h .
 h x . x h
 H . t . H
 h x . x h
 . h H h .

Where the 'H' positions simply require that we move 't' one step in that direction.
For the 'h' positions, we need to move diagonally into one of the 'x' positions.

'''

def update_rope(R, dir):
    # Move the Head knot - always
    if dir == 'R':
        R[0][0] += 1
    elif dir == 'D':
        R[0][1] -= 1
    elif dir == 'L':
        R[0][0] -= 1
    else: # 'U'
        R[0][1] += 1

    # Move the rest of the knots
    for r in range(1,len(R)):
        if abs(R[r][0]-R[r-1][0]) <= 1 and abs(R[r][1]-R[r-1][1]) <= 1:
            # The prev knot is within 1 length of the current knot, we can stop
            break
        # We're now more than 1 length from the previous knot
        if R[r-1][0] > R[r][0]:
            # Moving explicitly right
            R[r][0] += 1
            # Check if we need to move diagonally
            if R[r-1][1] > R[r][1]:
                R[r][1] += 1
            elif R[r-1][1] < R[r][1]:
                R[r][1] -= 1
        elif R[r-1][0] < R[r][0]:
            # Moving explicitly left
            R[r][0] -= 1
            # Check if we need to move diagonally
            if R[r-1][1] > R[r][1]:
                R[r][1] += 1
            elif R[r-1][1] < R[r][1]:
                R[r][1] -= 1
        else:
            # Moving explicitly up or down
            if R[r-1][1] > R[r][1]:
                R[r][1] += 1
            else:
                R[r][1] -= 1
    return R

def count_tails(rope):
    tvisited = set()
    tvisited.add(tuple(rope[-1]))
    for m in input_lines:
        tok = m.split()
        dir, amt = tok[0], int(tok[1])
        for _ in range(amt):
            rope = update_rope(rope, dir)
            tvisited.add(tuple(rope[-1]))
    return len(tvisited)

# Part 1
rope = [[0,0] for _ in range(2)]
part1(count_tails(rope))

# Part 2
rope = [[0,0] for _ in range(10)]
part2(count_tails(rope))


# -*- coding: utf-8 -*-
"""
Created on Thu Nov 21 09:55:45 2019

@author: HP
Site: Leetcode
Category: Medium
"""

class Solution(object):

    def longestCommonSubsequence2(self, text1, text2):
        """
        :type text1: str
        :type text2: str
        :rtype: int
        """
        memo = {}

        for i in range (len(text1)+1):
            for j in range(len(text2)+1):
                memo[(i, j)] = 0

        for i in range (len(text1)-1, -1, -1):
            for j in range(len(text2)-1, -1, -1):
                if(text1[i] == text2[j]):
                    memo[(i,j)] = 1 + memo[(i+1,j+1)]
                else:
                    memo[(i,j)] = max(memo[(i+1,j)], memo[(i,j+1)])

        return memo[(0,0)]

    def longestCommonSubsequence(self, text1, text2):
        """
        :type text1: str
        :type text2: str
        :rtype: int
        """

        return self.helper(text1, text2, 0, 0, {})

    def helper(self, x, y, i, j, memo):

        if((i == len(x)) or (j == len(y))):
            return 0

        if((i,j) in memo):
            return memo[(i,j)]

        if(x[i] == y[j]):
            memo[(i,j)] = 1 + self.helper(x, y, i+1, j+1, memo)

        else:
            memo[(i,j)] = max(self.helper(x, y, i+1, j, memo), self.helper(x, y, i, j+1, memo))

        return memo[(i,j)]