"""
Command-line script which automates the exporting, munging, cleaning, and saving operations involved in generating
the core dataset of interest in this project.
"""
from lxml import etree
from tqdm import tqdm
import pandas as pd
import os
import argparse
import subprocess

parser = argparse.ArgumentParser(description="""
Parse an XML dump of raw Wargame: Red Dragon internal unit value information into a unified CSV file.
""")
parser.add_argument("path", help="A filepath to the folder containing XML dumps to be processed (e.g. "
                                 "C:\\Users\\Alex\\Desktop\\wargame-analysis\\raws).")
parser.add_argument("version", help="The version of Wargame: Red Dragon to be processed (e.g. 510049986). Should be a "
                                    "subfolder of the filepath above, whose contents are generated using the "
                                    "Wargame XML Exporter tool.")
parser.add_argument("output", help="A filepath to the destination folder this script will write its output to.")
parser.add_argument('--fobs', dest='fobs',  action='store_true', help="enable export FOB buildings to seperate csv file")

def get_id(table):
    return table.items()[0][1]

def get_attribute(table, attr):
    """
    Given an XML element representing a table within everything.ndfbin and an attribute of interest, returns the
    contents of that attribute.
    """
    return table.find(attr).text

def get_collection(table, attr):
    """
    Given an XML element representing a table within everything.ndfbin and an attribute Collection of interest,
    returns the contents of that attribute's Collection.
    """
    elements = table.find(attr)
    values = [element.text for element in elements]
    return values

def get_module(table, module_name, xmlpaths, map_name=None):
    """
    Given an XML element representing a table within everything.ndfbin and an attribute Module reference of interest,
    returns that module if it exists and None if it does not.

    If the table element is listed with a map name matching a substring of itself (which happens in most cases),
    this method can be called with mapname=None. However, if the module we want has some other map name---for
    example, ModernWarfareScannerDescriptor is listed under just Scanner---pass what that map name is as mapname.
    """
    if not map_name:
        map_name = module_name.replace("ModuleDescriptor", "").replace("Descriptor", "")[1:]
    modules = [module.text for module in table.find("Modules")]
    try:
        selector_module_text = list(filter(lambda module: map_name in module, modules))[0]
        selector_module_id = selector_module_text.split(":")[-1].split(" ")[1]
        selector = xmlpaths['TModuleSelector.xml'].find("TModuleSelector[@id='{0}']".format(selector_module_id))
        pointer_text = selector.find("Default").text
        pointer_id = pointer_text.split(":")[-1].split(" ")[1]
        pointer_kind = pointer_text.split(":")[-1].split(" ")[-1]
        module = xmlpaths['{0}.xml'.format(pointer_kind)]\
            .find("{0}[@id='{1}']".format(pointer_kind, pointer_id))
        return module
    except IndexError:
        return None

def get_object_reference(table, attr, xmlpaths):
    """
    Given an XML element representing a table within everything.ndfbin and an attribute containing a reference to
    another table, returns the XML element representing that table.

    This is distinct from get_module, above, which must handle two levels of indirection.
    """
    try:
        module_id = table.find(attr).text.split(":")[-1].split(" ")[1]
    except IndexError:
        return None
    module_name = table.find(attr).text.split(":")[-1].split(" ")[-1]
    module = xmlpaths['{0}.xml'.format(module_name)] \
        .find("{0}[@id='{1}']".format(module_name, module_id))
    return module

def get_object_reference_list(table, attr, xmlpaths):
    """
    Same as get_object_reference, but applies to a list of them.
    """
    objects = get_collection(table, attr)
    ret = []
    for object in objects:
        module_id = object.split(":")[-1].split(" ")[1]
        module_name = object.split(":")[-1].split(" ")[-1]
        module = xmlpaths['{0}.xml'.format(module_name)] \
            .find("{0}[@id='{1}']".format(module_name, module_id))
        ret.append(module)
    return ret

def get_token(table, attr, lookup):
    """
    Returns a token from a lookup table.
    """
    hash = get_attribute(table, attr)
    return lookup[lookup['Hash'] == hash].iloc[0]['String']

def get_deck_id(unit, xmlpaths):
    unit_id = unit.get("id")
    if unit.find("Nationalite").text == "1":
        table = "PactUnitIds"
    else:
        table = "OtanUnitIds"
    for element in xmlpaths['TShowRoomDeckSerializer.xml'].findall(".//{0}/*".format(table)):
        if element.text.split()[5] == unit_id:
            return element.text.split()[1]

def serialize_fobs(fob, xmlpaths, localization):
    srs = pd.Series()
    srs['ID'] = get_id(fob)
    srs['DeckID'] = get_deck_id(fob, xmlpaths)

    for attr in ["ClassNameForDebug", "Category", "Factory", "Nationalite", "_ShortDatabaseName", "MotherCountry"]:
        srs[attr] = get_attribute(fob, attr)
    for attr in ["ProductionPrice", "MaxDeployableAmount", "UnitTypeTokens"]:
        srs[attr] = get_collection(fob, attr)

    # for attr in ["SupplyCapacity", "DeploymentDuration", "WithdrawalDuration", "SupplyPriority"]:
    #     srs[attr] = get_attribute(supply, attr)

    if "Building_FOB" in srs["_ShortDatabaseName"]:
        # null in non fob enties
        srs["NameInMenuToken"] = get_attribute(fob, "NameInMenuToken")
        srs["NameInMenu"] = get_token(fob, "NameInMenuToken", localization)
        return srs

def serialize_unit(unit, xmlpaths, localization):
    srs = pd.Series()

    ######
    # ID #
    ######
    srs['ID'] = get_id(unit)
    srs['DeckID'] = get_deck_id(unit, xmlpaths)

    ########################
    # TOP-LEVEL ATTRIBUTES #
    ########################
    for attr in ["_ShortDatabaseName", "ClassNameForDebug", "StickToGround", "ManageUnitOrientation",
                 "HitRollSizeModifier", "IconeType", "PositionInMenu", "AliasName", "Category", "AcknowUnitType",
                 "TypeForAcknow", "Nationalite", "MotherCountry", "ProductionYear", "MaxPacks", "Factory",
                 "ProductionTime", "CoutEtoile", "UnitMovingType", "VitesseCombat", "IsPrototype", "Key",
                 "HitRollECMModifier"]:
        srs[attr] = get_attribute(unit, attr)
    for attr in ["ProductionPrice", "MaxDeployableAmount", "ShowInMenu", "UnitTypeTokens"]:
        srs[attr] = get_collection(unit, attr)
    upgrade_path = get_object_reference(unit, "UpgradeRequire", xmlpaths)
    if upgrade_path is not None:
        srs["UpgradeRequired"] = get_id(upgrade_path)
    death_explosion = get_object_reference(unit, "DeathExplosionAmmo", xmlpaths)
    if death_explosion is not None:
        srs["DeathExplosionID"] = get_id(death_explosion)
        for attr in ["SuppressDamages", "RadiusSplashSuppressDamages", "Arme", "RadiusSplashPhysicalDamages"]:
            srs["DeathExplosion{0}".format(attr)] = get_attribute(death_explosion, attr)

    ################
    # IN-GAME NAME #
    ################
    srs["NameInMenuToken"] = get_attribute(unit, "NameInMenuToken")
    srs["NameInMenu"] = get_token(unit, "NameInMenuToken", localization)

    ########
    # TYPE #
    ########
    unit_type = get_module(unit, "TTypeUnitModuleDescriptor", xmlpaths)
    for attr in ["TypeUnitValue", "UnitInfoJaugeType", "Training", "NameInMenuToken", "CIWS", "Sailing"]:
        srs[attr] = get_attribute(unit_type, attr)
    # The "Filters" field is not recoverable because it is not exported properly in the XML.

    ############
    # POSITION #
    ############
    position = get_module(unit, "TPositionDescriptor", xmlpaths)
    if position is not None:
        for attr in ["LowAltitudeFlyingAltitude", "NearGroundFlyingAltitude"]:
            srs[attr] = get_attribute(position, attr)

    ##############
    # EXPERIENCE #
    ##############
    experience = get_module(unit, "TModernWarfareExperienceModuleDescriptor", xmlpaths, map_name="Experience")
    if experience is not None:
        for attr in ["CanWinExperience", "ExperienceGainBySecond", "KillExperienceBonus"]:
            srs[attr] = get_attribute(experience, attr)

    ###########
    # COMMAND #
    ###########
    command = get_module(unit, "TCommandManagerModuleDescriptor", xmlpaths)
    if command is not None:
        srs["IsCommandUnit"] = True

    ##########
    # VISION #
    ##########
    scanner = get_module(unit, "TModernWarfareScannerModuleDescriptor", xmlpaths, map_name="Scanner :")
    # The map_name parameter in this case is a bit tortured. This is because Scanner is a substring of
    # ScannerConfiguration, and both are present if one or the other is, so to catch the former we have to add some
    # of the surrounding formatting text.
    if scanner is not None:
        vis_roll_rule = get_object_reference(scanner, "VisibilityRollRule", xmlpaths)
        srs["TimeBetweenEachIdentifyRoll"] = get_attribute(vis_roll_rule, "TimeBetweenEachIdentifyRoll")
        srs["IdentifyBaseProbability"] = get_attribute(vis_roll_rule, "IdentifyBaseProbability")
    scanner_c = get_module(unit, "TScannerConfigurationDescriptor", xmlpaths)
    if scanner_c is not None:
        for attr in ["DetectionTBA", "PorteeVision", "OpticalStrength", "OpticalStrengthAltitude", "PorteeVisionTBA",
                     "OpticalStrengthAntiradar"]:
            srs[attr] = get_attribute(scanner_c, attr)

    ########
    # FUEL #
    ########
    fuel = get_module(unit, "TFuelModuleDescriptor", xmlpaths)
    if fuel is not None:
        srs["FuelCapacity"] = get_attribute(fuel, "FuelCapacity")
        srs["FuelMoveDuration"] = get_attribute(fuel, "FuelMoveDuration")

    ############
    # MOVEMENT #
    ############
    movement = get_module(unit, "MouvementHandler", xmlpaths)
    movement_kind = movement.tag
    if "LandVehicle" in movement_kind:
        for attr in ["Maxspeed", "UnitMovingType", "SpeedBonusOnRoad", "TempsDemiTour", "MaxAcceleration",
                     "MaxDeceleration", "VehicleSubType", "TerrainsToIgnoreMask"]:
            srs[attr] = get_attribute(movement, attr)
    elif "Helicopter" in movement_kind:
        for attr in ["Maxspeed", "MaxAcceleration", "MaxDeceleration", "UnitMovingType", "CyclicManoeuvrability",
                     "GFactorLimit", "LateralSpeed", "Mass", "MaxInclination", "RotorArea", "TorqueManoeuvrability",
                     "UpwardSpeed", "TempsDemiTour"]:
            srs[attr] = get_attribute(movement, attr)
    elif "Airplane" in movement_kind:
        for attr in ["Maxspeed", "UnitMovingType", "FlyingAltitude", "MinimalAltitude", "GunMuzzleSpeed"]:
            srs[attr] = get_attribute(movement, attr)

    # TODO: Transportable
    #################
    # TRANSPORTABLE #
    #################
    # # Transportable is a special case, because in the Modules list instead of linking by way of a ModuleSelector it
    # # is placed in the table directly.
    modules = [module.text for module in unit.find("Modules")]
    try:
        transportable_module_text = list(filter(lambda module: "Transportable" in module, modules))[0]
        transportable_module_id = transportable_module_text.split(":")[-1].split(" ")[1]
        transportable = xmlpaths['TTransportableModuleDescriptor.xml'].find("TTransportableModuleDescriptor[@id='{0}']"\
            .format(transportable_module_id))
        if transportable is not None:
            srs["SuppressDamageRatioIfTransporterKilled"] = get_attribute(transportable,
                                                                          "SuppressDamageRatioIfTransporterKilled")
            spawns = get_object_reference_list(transportable, "TransportListAvailableForSpawn", xmlpaths)
            transporters = [get_id(t) for t in spawns]
            srs["Transporters"] = transporters
    except (ValueError, IndexError):
        pass

    ##########
    # SUPPLY #
    ##########
    supply = get_module(unit, "TSupplyModuleDescriptor", xmlpaths)
    if supply is not None:
        for attr in ["SupplyCapacity", "DeploymentDuration", "WithdrawalDuration", "SupplyPriority"]:
            srs[attr] = get_attribute(supply, attr)

    ###########
    # WEAPONS #
    ###########
    weapon_manager = get_module(unit, "TWeaponManagerModuleDescriptor", xmlpaths)
    if weapon_manager is not None:
        # SalvoIsMainSalvo was located elsewhere in the 4x branch versions.
        for attr in ["Salves"]:
            srs[attr] = get_collection(weapon_manager, attr)
        if str(parser.parse_args().version)[0] == "5":
            srs["SalvoIsMainSalvo"] = get_collection(weapon_manager, "SalvoIsMainSalvo")
        weapons = []
        for turret in get_object_reference_list(weapon_manager, "TurretDescriptorList", xmlpaths):
            turret_kind = turret.tag
            for weapon in get_object_reference_list(turret, "MountedWeaponDescriptorList", xmlpaths):
                weapon_srs = pd.Series()
                # First pick up all of the turret-level info for this weapon.
                if "TwoAxis" in turret_kind:
                    for attr in ["Tag", "TagIndex", "VitesseRotation", "AngleRotationMax", "AngleRotationMaxPitch",
                                 "AngleRotationBasePitch", "AngleRotationMinPitch", "AngleRotationBase"]:
                        weapon_srs[attr] = get_attribute(turret, attr)
                elif "TurretUnit" in turret_kind:
                    for attr in ["Tag", "TagIndex", "AngleRotationMax", "AngleRotationMaxPitch",
                                 "AngleRotationMinPitch"]:
                        weapon_srs[attr] = get_attribute(turret, attr)
                elif "TurretBombardier" in turret_kind:
                    for attr in ["FlyingAltitude", "FlyingSpeed"]:
                        weapon_srs[attr] = get_attribute(turret, attr)
                elif "TurretInfanterie" in turret_kind:
                    pass  # No variables of interest.
                # Then pick up the weapon-level variables.
                for attr in ["SalvoStockIndex", "SalvoStockIndex_ForInterface", "TirEnMouvement", "TirContinu",
                             "AnimateOnlyOneSoldier"]:
                    weapon_srs[attr] = get_attribute(weapon, attr)
                # The pick up the ammunition-level variables.
                ammo = get_object_reference(weapon, "Ammunition", xmlpaths)
                for attr in ["Arme", "ProjectileType", "Puissance", "TempsEntreDeuxTirs", "TempsEntreDeuxFx",
                             "PorteeMaximale", "PorteeMaximaleBateaux", "AngleDispersion", "RadiusSplashSuppressDamages",
                             "SuppressDamages", "RayonPinned", "TirIndirect", "TirReflexe", "TempsEntreDeuxSalves",
                             "NbrProjectilesSimultanes", "NbTirParSalves", "AffichageMunitionParSalve", "Level",
                             "FireDescriptor", "FireTriggeringProbability", "RadiusSplashPhysicalDamages",
                             "PhysicalDamages", "WeaponCursorType", "PorteeMinimale", "PorteeMinimaleBateaux",
                             "DispersionAtMinRange", "DispersionAtMaxRange", "NoiseDissimulationMalus", "TempsDeVisee",
                             "AffichageMenu", "SupplyCost", "SmokeDescriptor", "PorteeMaximaleTBA", "PorteeMinimaleTBA",
                             "PorteeMaximaleHA", "MissileTimeBetweenCorrections", "Guidance", "EfficaciteSelonPortee",
                             "AffecteParNombre", "NeedModelChange", "IsFireAndForget", "IgnoreInflammabilityConditions",
                             "InterdireTirReflexe", "CorrectedShotDispersionMultiplier", "IsSubAmmunition",
                             "RandomDispersion", "TempsAnimation", "PorteeMaximaleProjectile",
                             "PorteeMinimaleProjectile", "PorteeMinimaleHA", "Name", "TypeName", "TypeArme", "Caliber"]:
                    weapon_srs[attr] = get_attribute(ammo, attr)
                acc = get_object_reference(ammo, "HitRollRule", xmlpaths)
                for attr in ["MinimalHitProbability", "MinimalCritProbability", "HitProbability",
                             "HitProbabilityWhileMoving"]:
                    weapon_srs[attr] = get_attribute(acc, attr)
                is_missile = get_attribute(ammo, "MissileDescriptor")
                if "TUnite" in is_missile:
                    missile = get_object_reference(ammo, "MissileDescriptor", xmlpaths)
                    modules = [module.text for module in missile.find("Modules")]
                    missile_text = list(filter(lambda module: "Mouvement" in module, modules))[0]
                    missile_module_id = missile_text.split(":")[-1].split(" ")[1]
                    missile_move = xmlpaths['TMouvementHandler_GuidedMissileDescriptor.xml'].find(
                        "TMouvementHandler_GuidedMissileDescriptor[@id='{0}']" \
                        .format(missile_module_id))
                    weapon_srs["MissileMaxSpeed"] = get_attribute(missile_move, "Maxspeed")
                    weapon_srs["MissileMaxAcceleration"] = get_attribute(missile_move, "MaxAcceleration")
                # Add the weapon to the list.
                weapons.append(weapon_srs)
            # Attach all of the weapons to the dataset!
        for i, weapon in enumerate(weapons, start=1):
            weapons[i - 1].index = ["Weapon{0}{1}".format(i, attr.replace("Weapon", ""))\
                                    for attr in weapons[i - 1].index]
            srs = srs.append(weapon)

    ##########
    # DAMAGE #
    ##########
    damage = get_module(unit, "TModernWarfareDamageModuleDescriptor", xmlpaths, map_name="Damage")
    if damage is not None:
        for attr in ["MaxDamages", "AutoOrientation", "Transporter", "IsTargetableAsBoat"]:
            srs[attr] = get_attribute(damage, attr)
        common_damage = get_object_reference(damage, "CommonDamageDescriptor", xmlpaths)
        for attr in ["StunDamagesRegen", "StunDamagesToGetStunned", "SuppressDamagesRegenRatioOutOfRange",
                     "MaxSuppressionDamages"]:
            srs[attr] = get_attribute(common_damage, attr)
        for attr in ["PaliersSuppressDamages", "PaliersPhysicalDamages"]:
            srs[attr] = get_collection(common_damage, attr)
        armor = get_object_reference(common_damage, "BlindageProperties", xmlpaths)
        for side in ["Front", "Sides", "Rear", "Top"]:
            a = get_attribute(get_object_reference(armor, "ArmorDescriptor{0}".format(side), xmlpaths), "BaseBlindage")
            srs["Armor{0}".format(side)] = a

    ###########
    # STEALTH #
    ###########
    visibility = get_module(unit, "TVisibilityModuleDescriptor", xmlpaths)
    srs["UnitStealthBonus"] = get_attribute(visibility, "UnitStealthBonus")

    # Return
    return srs

def main():
    fullpath = "{0}/{1}/{2}".format(parser.parse_args().path, parser.parse_args().version,
                                    "pc/ndf/patchable/gfx").replace("/", "\\")
    xmlpaths = dict()
    for root, dirs, files in os.walk(fullpath):
        for name in files:
            if os.path.splitext(name)[1] == '.xml' :
                xmlpaths[name] = etree.parse(os.path.join(root, name))

    localizationpath = "{0}/{1}/{2}".format(parser.parse_args().path, parser.parse_args().version,
                                     "ZZ_Win/pc/localisation/us/localisation/unites_fixed.csv").replace("/", "\\")
    localization = pd.read_csv(localizationpath, encoding='utf-8', index_col=0)
    units = xmlpaths['TUniteAuSolDescriptor.xml'].findall("TUniteAuSolDescriptor")
    # test = list(units)[:20]
    df = pd.concat([serialize_unit(unit, xmlpaths, localization) for unit in tqdm(units)], axis=1).T
    subprocess.run(["mkdir", (parser.parse_args().output + "/" + parser.parse_args().version).replace("/", "\\")],
                   shell=True)
    df.to_csv(parser.parse_args().output + "/" + parser.parse_args().version +  "/raw_data.csv")

    if parser.parse_args().fobs:
        fobs = xmlpaths['TUniteDescriptor.xml'].findall("TUniteDescriptor")
        fb = pd.concat([serialize_fobs(fob, xmlpaths, localization) for fob in tqdm(fobs)], axis=1).T
        fb.to_csv(parser.parse_args().output + "/" + parser.parse_args().version +  "/raw_fobs.csv")

if __name__ == "__main__":
    main()


'''

在python中，模块时代吗最值的一种方式，把功能相近的函数方法哦一个文件中，一个文件（.py）就是一个模块（module）
模块名就是文件名去掉后缀py，这样做的好处是：

     --提高代码的可服用，课维护性。一个模块编写完毕后，可以很方便的在其他项目中导入
     --解决了命名冲突，不同模块中相同的明敏不会冲突

1.自定义一些模块
2.使用系统的模块

调用其他模块的方式:
  1.import 模块名
  2.from 模块名 import 变量 函数 类 (多个导入 逗号间隔)
  3.from 模块名 import *  该模块内容全部导入
    单数如果想限制获取的内容， 可以在该模块中 设置属性__all__ = []
  4.无论是import还是from的形式，都会将模块内容进行加载
    如果不希望进行调用。就会用到__name__
    在自己的模块里面__name__ 的值是__main__
    如果在其他模块中通过导入的方式调用的话：__name__的值是：模块名
'''

# import calculate
from calculate import *  #add,number,Calculate
#包的导入  from 后面就是包名.模块名  import 后面是 模块名或是 变量 函数 类

from objectOriented.object15_singleton import Singleton
singletong = Singleton()
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 使用模块中的函数  模块名.变量 函数  类
# sum1 = calculate.add(*list1)
# print(sum1)
# # 使用模块的变量
# print(calculate.name)
# # 使用模块中的类
# cal = calculate.Calculate(88)
# cal.test()
# calculate.Calculate.test1()

sum1 = add(*list1)
print(sum1)
# 使用模块的变量
print(number)
# 使用模块中的类
cal = Calculate(88)
cal.test()
Calculate.test1()

print(dir())


name = input("Choose you name: " )

print("Welcome", name, "I was waiting for you... let's start!!!")
ans = None

questions = {"Everyone can open it, but no one can close it what's that?": [
    "egg",
    "Well done you find the first solution... Let's move to the next one...",
    ],
    "Is huge, massive and dark what's that?": [
    "universe",
    "Good Job, you will have another one and you're done with game"],
    "You said Hi only if is UP... What's that?": [
    "flag",
    "And that was the last one"]}

for q in questions:
    while True:
        ans = input(q)
        if ans == questions[q][0]:
            print(questions[q][1])
            break
        else:
            print("Close but not enough")


import isce
import xml.etree.ElementTree as ElementTree
from collections import defaultdict
import datetime
import isceobj
from isceobj.Util import Poly1D, Poly2D
from isceobj.Planet.Planet import Planet
from isceobj.Orbit.Orbit import StateVector, Orbit
from isceobj.Orbit.OrbitExtender import OrbitExtender
from isceobj.Planet.AstronomicalHandbook import Const
from iscesys.Component.Component import Component
from iscesys.DateTimeUtil.DateTimeUtil import DateTimeUtil as DTUtil
from .GRDProduct import GRDProduct
import os
import glob
import json
import numpy as np
import shelve

SAFE = Component.Parameter('safe',
            public_name = 'safe',
            default = None,
            type = str,
            doc = 'SAFE folder with the GRD product')

POLARIZATION = Component.Parameter('polarization',
            public_name = 'polarization',
            default = None,
            type = str,
            doc = 'Polarization to unpack')

ORBIT_DIR = Component.Parameter('orbitDir',
            public_name = 'orbit directory',
            default = None,
            type = str,
            doc = 'Directory to search for orbit data')

ORBIT_FILE = Component.Parameter('orbitFile',
            public_name = 'orbit file',
            default = None,
            type = str,
            doc = 'External orbit file with state vectors')

OUTPUT = Component.Parameter('output',
            public_name = 'output directory',
            default = None,
            type = str,
            doc = 'Directory where the data gets unpacked')

SLANT_RANGE_FILE = Component.Parameter('slantRangeFile',
            public_name = 'slant range file',
            default = None,
            type = str,
            doc = 'Slant range file at full resolution')

####List of facilities
PRODUCT = Component.Facility('product',
            public_name='product',
            module = 'isceobj.Sensor.GRD',
            factory = 'createGRDProduct',
            args = (),
            mandatory = True,
            doc = 'GRD Product populated by the reader')

class Sentinel1(Component):
    """
        A Class representing Sentinel1 data
    """

    family = 's1grd'
    logging = 'isce.sensor.grd.s1'

    parameter_list = (SAFE,
                      POLARIZATION,
                      ORBIT_DIR,
                      ORBIT_FILE,
                      OUTPUT,
                      SLANT_RANGE_FILE)

    facility_list = (PRODUCT,)

    def __init__(self):
        Component.__init__(self)
        self.xml = None
        self.tiff = None
        self.calibrationXml = None
        self.noiseXml = None

        self.manifest = None
        self.noiseCorrectionApplied = False

        self.betaLUT = None
        self.gr2srLUT = None
        self.noiseRangeLUT = None
        self.noiseAzimuthLUT = None

        self._xml_root=None

    def validateUserInputs(self):
        '''
        Validate inputs provided by user.
        Populat tiff and xml list using SAFE folder names.
        '''

        import zipfile
        import fnmatch

        if self.safe is None:
            raise Exception('SAFE directory is not provided')

        if self.polarization in ['',None]:
            raise Exception('Polarization is not provided')

        ###Check if zip file / unpacked directory is provided.
        iszipfile = False
        if self.safe.endswith('.zip'):
            iszipfile = True
            with zipfile.ZipFile(self.safe, 'r') as zf:
                namelist = zf.namelist()

        ####First find VV annotation file
        swathid = 's1?-iw-grd-' + self.polarization.lower()

        if iszipfile:
            #Find XML file
            patt = os.path.join('*.SAFE', 'annotation', swathid+'*')
            match = fnmatch.filter(namelist, patt)

            if len(match) == 0 :
                raise Exception('Annotation file for {0} not found in {1}'.format(self.polarization, self.safe))

            self.xml = os.path.join('/vsizip', self.safe, match[0])

            #Find TIFF file
            patt = os.path.join('*.SAFE', 'measurement', swathid+'*')
            match = fnmatch.filter(namelist, patt)

            if len(match) == 0 :
                raise Exception('Annotation file found for {0} but no measurement in {1}'.format(self.polarization, self.safe))

            self.tiff = os.path.join('/vsizip', self.safe, match[0])

            #Find Calibration file
            patt = os.path.join('*.SAFE', 'annotation', 'calibration', 'calibration-'+swathid+'*')
            match = fnmatch.filter(namelist, patt)

            if len(match) == 0 :
                raise Exception('Annotation file found for {0} but no calibration in {1}'.format(self.polarization, self.safe))

            self.calibrationXml = os.path.join('/vsizip', self.safe, match[0])

            #Find Noise file
            patt = os.path.join('*.SAFE', 'annotation', 'calibration', 'noise-'+swathid+'*')
            match = fnmatch.filter(namelist, patt)

            if len(match) == 0 :
                raise Exception('Annotation file found for {0} but no noise in {1}'.format(self.polarization, self.safe))

            self.noiseXml = os.path.join('/vsizip', self.safe, match[0])

            patt = os.path.join('*.SAFE', 'manifest.safe')
            match = fnmatch.filter(namelist, patt)
            if len(match) == 0:
                raise Exception('No manifest file found in {0}'.format(self.safe))
            self.manifest = os.path.join('/vsizip', self.safe, match[0])

        else:

            ####Find annotation file
            patt = os.path.join( self.safe, 'annotation', swathid + '*')
            match = glob.glob(patt)

            if len(match) == 0:
                raise Exception('Annotation file for {0} not found in {1}'.format(self.polarization, self.safe))

            self.xml = match[0]

            ####Find TIFF file
            patt = os.path.join( self.safe, 'measurement', swathid+'*')
            match = glob.glob(patt)

            if len(match) == 0:
                raise Exception('Annotation file found for {0} but not measurement in {1}'.format(self.polarization, self.safe))

            self.tiff= match[0]

            ####Find calibration file
            patt = os.path.join( self.safe, 'annotation', 'calibration', 'calibration-' + swathid + '*')
            match = glob.glob(patt)

            if len(match) == 0 :
                raise Exception('Annotation file found for {0} but not calibration in {1}'.format(self.polarization, self.safe))

            self.calibrationXml= match[0]

            ####Find noise file
            patt = os.path.join( self.safe, 'annotation', 'calibration', 'noise-' + swathid + '*')
            match = glob.glob(patt)

            if len(match) == 0 :
                raise Exception('Annotation file found for {0} but not noise in {1}'.format(self.polarization, self.safe))

            self.noiseXml = match[0]

	    ####Find manifest file
            self.manifest = os.path.join(self.safe, 'manifest.safe')

        print('XML: ', self.xml)
        print('TIFF: ', self.tiff)
        print('CALIB: ', self.calibrationXml)
        print('NOISE: ', self.noiseXml)
        print('MANIFEST: ', self.manifest)

        return

    def parse(self):
        import zipfile

        self.validateUserInputs()

        if '.zip' in self.xml:
            try:
                parts = self.xml.split(os.path.sep)
                zipname = os.path.join('/',*(parts[:-3]))
                fname = os.path.join(*(parts[-3:]))

                with zipfile.ZipFile(zipname, 'r') as zf:
                    xmlstr = zf.read(fname)
            except:
                raise Exception('Could not read xml file {0}'.format(self.xml))
        else:
            try:
                with open(self.xml, 'r') as fid:
                    xmlstr = fid.read()
            except:
                raise Exception('Could not read xml file {0}'.format(self.xml))

        self._xml_root = ElementTree.fromstring(xmlstr)

        self.populateMetadata()
        self.populateBbox()

        ####Try and locate an orbit file
        if self.orbitFile is None:
            if self.orbitDir is not None:
                self.orbitFile = self.findOrbitFile()
                print('Found this orbitfile: %s' %self.orbitFile)

        ####Read in the orbits
        if '_POEORB_' in self.orbitFile:
            orb = self.extractPreciseOrbit()
        elif '_RESORB_' in self.orbitFile:
            orb = self.extractOrbit()

        self.product.orbit.setOrbitSource('Header')
        for sv in orb:
            self.product.orbit.addStateVector(sv)

        self.populateIPFVersion()
        self.extractBetaLUT()
        self.extractNoiseLUT()

    def getxmlattr(self, path, key):
        try:
            res = self._xml_root.find(path).attrib[key]
        except:
            raise Exception('Cannot find attribute %s at %s'%(key, path))

        return res

    def getxmlvalue(self, path):
        try:
            res = self._xml_root.find(path).text
        except:
            raise Exception('Tag= %s not found'%(path))

        if res is None:
            raise Exception('Tag = %s not found'%(path))

        return res

    def getxmlelement(self, path):
        try:
            res = self._xml_root.find(path)
        except:
            raise Exception('Cannot find path %s'%(path))

        if res is None:
            raise Exception('Cannot find path %s'%(path))

        return res

    def convertToDateTime(self, string):
        dt = datetime.datetime.strptime(string,"%Y-%m-%dT%H:%M:%S.%f")
        return dt

    def populateMetadata(self):
        """
            Create metadata objects from the metadata files
        """
        ####Set each parameter one - by - one
        mission = self.getxmlvalue('adsHeader/missionId')
        swath = self.getxmlvalue('adsHeader/swath')
        polarization = self.getxmlvalue('adsHeader/polarisation')
        orbitnumber = int(self.getxmlvalue('adsHeader/absoluteOrbitNumber'))
        frequency = float(self.getxmlvalue('generalAnnotation/productInformation/radarFrequency'))
        passDirection = self.getxmlvalue('generalAnnotation/productInformation/pass')

        groundRangePixelSize = float(self.getxmlvalue('imageAnnotation/imageInformation/rangePixelSpacing'))
        azimuthPixelSize = float(self.getxmlvalue('imageAnnotation/imageInformation/azimuthPixelSpacing'))
        azimuthTimeInterval = float(self.getxmlvalue('imageAnnotation/imageInformation/azimuthTimeInterval'))

        lines = int(self.getxmlvalue('imageAnnotation/imageInformation/numberOfLines'))
        samples = int(self.getxmlvalue('imageAnnotation/imageInformation/numberOfSamples'))

        slantRangeTime = float(self.getxmlvalue('imageAnnotation/imageInformation/slantRangeTime'))
        startingSlantRange = float(self.getxmlvalue('imageAnnotation/imageInformation/slantRangeTime'))*Const.c/2.0
        incidenceAngle = float(self.getxmlvalue('imageAnnotation/imageInformation/incidenceAngleMidSwath'))

        sensingStart = self.convertToDateTime( self.getxmlvalue('imageAnnotation/imageInformation/productFirstLineUtcTime'))
        sensingStop = self.convertToDateTime( self.getxmlvalue('imageAnnotation/imageInformation/productLastLineUtcTime'))

        ####Sentinel is always right looking
        lookSide = -1

        ###Read ascending node for phase calibration
        ascTime = self.convertToDateTime(self.getxmlvalue('imageAnnotation/imageInformation/ascendingNodeTime'))

        ###Noise correction
        correctionApplied = self.getxmlvalue('imageAnnotation/processingInformation/thermalNoiseCorrectionPerformed').upper() == 'TRUE'

        self.product.lookSide = 'RIGHT'
        self.product.numberOfSamples = samples
        self.product.numberOfLines = lines
        self.product.startingGroundRange = 0.0
        self.product.startingSlantRange = startingSlantRange
        self.product.trackNumber = ((orbitnumber-73)%175) + 1
        self.product.orbitNumber = orbitnumber
        self.product.frameNumber = 1
        self.product.polarization = polarization
        self.product.passDirection = passDirection
        self.product.radarWavelength = Const.c / frequency
        self.product.groundRangePixelSize = groundRangePixelSize
        self.product.azimuthPixelSize = azimuthPixelSize
        self.product.azimuthTimeInterval = azimuthTimeInterval
        self.product.ascendingNodeTime = ascTime
        self.product.slantRangeTime = slantRangeTime
        self.product.sensingStart = sensingStart
        self.product.sensingStop = sensingStop
        self.noiseCorrectionApplied = correctionApplied

    def populateBbox(self, margin=0.1):
        '''
        Populate the bounding box from metadata.
        '''

        glist = self.getxmlelement('geolocationGrid/geolocationGridPointList')

        lat = []
        lon = []

        for child in glist:
            lat.append( float(child.find('latitude').text))
            lon.append( float(child.find('longitude').text))

        self.product.bbox = [min(lat) - margin, max(lat) + margin, min(lon) - margin, max(lon) + margin]
        print(self.product.bbox)
        return

    def populateIPFVersion(self):
        '''
        Get IPF version from the manifest file.
        '''

        if self.manifest is None:
            return

        nsp = "{http://www.esa.int/safe/sentinel-1.0}"

        if '.zip' in self.manifest:

            import zipfile
            parts = self.manifest.split(os.path.sep)
            zipname = os.path.join('/',*(parts[:-2]))
            fname = os.path.join(*(parts[-2:]))

            try:
                with zipfile.ZipFile(zipname, 'r') as zf:
                    xmlstr = zf.read(fname)
            except:
                raise Exception('Could not read manifest file : {0}'.format(self.manifest))
        else:
            try:
                with open(self.manifest, 'r') as fid:
                    xmlstr = fid.read()
            except:
                raise Exception('Could not read manifest file: {0}'.format(self.manifest))

        try:
            root = ElementTree.fromstring(xmlstr)

            elem = root.find('.//metadataObject[@ID="processing"]')
            rdict = elem.find('.//xmlData/' + nsp + 'processing/' + nsp + 'facility/' + nsp + 'software').attrib

            self.IPFversion = rdict['version']
            print('Setting IPF version to : ', self.IPFversion)

        except:
            print('Could not read version number successfully from manifest file: ', self.manifest)
            pass
        return

    def findOrbitFile(self):
        '''
        Find correct orbit file in the orbit directory.
        '''

        datefmt = "%Y%m%dT%H%M%S"
        types = ['POEORB', 'RESORB']
        filelist = []
        match = []
        timeStamp = self.product.sensingStart+(self.product.sensingStop - self.product.sensingStart)/2.

        for orbType in types:
            files = glob.glob( os.path.join(self.orbitDir, 'S1?_OPER_AUX_' + orbType + '_OPOD*'))
            filelist.extend(files)
            ###List all orbit files

        for result in filelist:
            fields = result.split('_')
            taft = datetime.datetime.strptime(fields[-1][0:15], datefmt)
            tbef = datetime.datetime.strptime(fields[-2][1:16], datefmt)
            print(taft, tbef)

            #####Get all files that span the acquisition
            if (tbef <= timeStamp) and (taft >= timeStamp):
                tmid = tbef + 0.5 * (taft - tbef)
                match.append((result, abs((timeStamp-tmid).total_seconds())))
            #####Return the file with the image is aligned best to the middle of the file
            if len(match) != 0:
                bestmatch = min(match, key = lambda x: x[1])
                return bestmatch[0]

        if len(match) == 0:
            raise Exception('No suitable orbit file found. If you want to process anyway - unset the orbitdir parameter')

    def extractOrbit(self):
        '''
        Extract orbit information from xml node.
        '''
        node = self._xml_root.find('generalAnnotation/orbitList')

        print('Extracting orbit from annotation XML file')
        frameOrbit = Orbit()
        frameOrbit.configure()

        for child in node:
            timestamp = self.convertToDateTime(child.find('time').text)
            pos = []
            vel = []
            posnode = child.find('position')
            velnode = child.find('velocity')
            for tag in ['x','y','z']:
                pos.append(float(posnode.find(tag).text))

            for tag in ['x','y','z']:
                vel.append(float(velnode.find(tag).text))

            vec = StateVector()
            vec.setTime(timestamp)
            vec.setPosition(pos)
            vec.setVelocity(vel)
            frameOrbit.addStateVector(vec)

        return frameOrbit

    def extractPreciseOrbit(self):
        '''
        Extract precise orbit from given Orbit file.
        '''
        try:
            fp = open(self.orbitFile,'r')
        except IOError as strerr:
            print("IOError: %s" % strerr)
            return

        _xml_root = ElementTree.ElementTree(file=fp).getroot()

        node = _xml_root.find('Data_Block/List_of_OSVs')

        orb = Orbit()
        orb.configure()

        margin = datetime.timedelta(seconds=40.0)
        tstart = self.product.sensingStart - margin
        tend = self.product.sensingStop + margin

        for child in node:
            timestamp = self.convertToDateTime(child.find('UTC').text[4:])

            if (timestamp >= tstart) and (timestamp < tend):

                pos = []
                vel = []

                for tag in ['VX','VY','VZ']:
                    vel.append(float(child.find(tag).text))

                for tag in ['X','Y','Z']:
                    pos.append(float(child.find(tag).text))

                vec = StateVector()
                vec.setTime(timestamp)
                vec.setPosition(pos)
                vec.setVelocity(vel)
#                print(vec)
                orb.addStateVector(vec)

        fp.close()

        return orb

    def extractBetaLUT(self):
        '''
        Extract Beta nought look up table from calibration file.
        '''

        from scipy.interpolate import RectBivariateSpline

        if self.calibrationXml is None:
            raise Exception('No calibration file provided')

        if '.zip' in self.calibrationXml:
            import zipfile
            parts = self.calibrationXml.split(os.path.sep)
            zipname = os.path.join('/',*(parts[:-4]))
            fname = os.path.join(*(parts[-4:]))

            try:
                with zipfile.ZipFile(zipname, 'r') as zf:
                    xmlstr = zf.read(fname)
            except:
                raise Exception('Could not read calibration file: {0}'.format(self.calibrationXml))
        else:
            try:
                with open(self.calibrationXml, 'r') as fid:
                    xmlstr = fid.read()
            except:
                raise Exception('Could not read calibration file: {0}'.format(self.calibrationXml))

        _xml_root = ElementTree.fromstring(xmlstr)

        node = _xml_root.find('calibrationVectorList')
        num = int(node.attrib['count'])

        lines = []
        pixels = []
        data = None

        for ii, child in enumerate(node):
            pixnode = child.find('pixel')
            nump = int(pixnode.attrib['count'])

            if ii==0:
                data = np.zeros((num,nump))
                pixels = [float(x) for x in pixnode.text.split()]

            lines.append( int(child.find('line').text))
            signode = child.find('betaNought')
            data[ii,:] = [float(x) for x in signode.text.split()]

        lines = np.array(lines)
        pixels = np.array(pixels)

        self.betaLUT = RectBivariateSpline(lines,pixels, data, kx=1, ky=1)

        if False:
            import matplotlib.pyplot as plt
            plt.figure()
            plt.imshow(data)
            plt.colorbar()
            plt.show()

        return

    def extractNoiseLUT(self):
        '''
        Extract Noise look up table from calibration file.
        '''

        from scipy.interpolate import interp1d, InterpolatedUnivariateSpline

        if self.noiseXml is None:
            raise Exception('No calibration file provided')

        if '.zip' in self.noiseXml:
            import zipfile
            parts = self.noiseXml.split('.zip/')
            zipname = parts[0] + '.zip'
            fname = parts[1]

            try:
                with zipfile.ZipFile(zipname, 'r') as zf:
                    xmlstr = zf.read(fname)
            except:
                raise Exception('Could not read noise file: {0}'.format(self.calibrationXml))
        else:
            try:
                with open(self.noiseXml, 'r') as fid:
                    xmlstr = fid.read()
            except:
                raise Exception('Could not read noise file: {0}'.format(self.calibrationXml))

        if float(self.IPFversion) < 2.90:
            noise_range_vector_name = "noiseVectorList"
            noise_range_lut_name = "noiseLut"
            has_azimuth_noise_vectors = False
            self.noiseAzimuthLUT = None
        else:
            noise_range_vector_name = "noiseRangeVectorList"
            noise_range_lut_name = "noiseRangeLut"
            has_azimuth_noise_vectors = True

        print("Extracting noise LUT's...")

        _xml_root = ElementTree.fromstring(xmlstr)

        node = _xml_root.find(noise_range_vector_name)
        num_vectors = int(node.attrib['count'])

        print("File contains {} range noise vectors.".format(num_vectors))

        full_samples_range = np.arange(self.product.numberOfSamples)
        noise_range_lut_indices = np.zeros((num_vectors,))
        noise_range_lut_values = np.zeros((num_vectors, self.product.numberOfSamples))

        for ii, child in enumerate(node):
            print("Processing range noise vector {}/{}".format(ii + 1, num_vectors))
            pixnode = child.find('pixel')

            sample_pixels = [float(x) for x in pixnode.text.split()]

            signode = child.find(noise_range_lut_name)
            vector = np.asarray([float(x) for x in signode.text.split()])
            vector_interpolator = InterpolatedUnivariateSpline(sample_pixels, vector, k=1)
            vector_interpolated = vector_interpolator(full_samples_range)

            noise_range_lut_indices[ii] = int(child.find('line').text)
            noise_range_lut_values[ii] = vector_interpolated

        self.noiseRangeLUT = interp1d(noise_range_lut_indices, noise_range_lut_values, kind='linear', axis=0, fill_value="extrapolate")

        if has_azimuth_noise_vectors:

            node = _xml_root.find("noiseAzimuthVectorList")
            num_vectors = int(node.attrib['count'])

            print("File contains {} azimuth noise blocks.".format(num_vectors))

            noise_azimuth_lut_indices = defaultdict(list)
            noise_azimuth_lut_values = defaultdict(list)

            for block_i, child in enumerate(node):
                print("Processing azimuth noise vector {}/{}".format(block_i + 1, num_vectors))
                linenode = child.find('line')
                signode = child.find("noiseAzimuthLut")
                block_range_start = int(child.find('firstRangeSample').text)
                block_range_end = int(child.find('lastRangeSample').text)
                block_azimuth_start = int(child.find('firstAzimuthLine').text)
                block_azimuth_end = int(child.find('lastAzimuthLine').text)
                block_line_index = [float(x) for x in linenode.text.split()]
                block_vector = [float(x) for x in signode.text.split()]
                block_line_range = np.arange(block_azimuth_start, block_azimuth_end + 1)

                if len(block_vector) > 1:
                    block_vector_interpolator = InterpolatedUnivariateSpline(block_line_index, block_vector, k=1)
                    for line in block_line_range:
                        noise_azimuth_lut_indices[line].extend([block_range_start, block_range_end])
                        noise_azimuth_lut_values[line].extend([block_vector_interpolator(line)] * 2)
                else:
                    for line in block_line_range:
                        noise_azimuth_lut_indices[line].extend([block_range_start, block_range_end])
                        noise_azimuth_lut_values[line].extend([block_vector[0]] * 2)

            self.noiseAzimuthLUT = (noise_azimuth_lut_indices, noise_azimuth_lut_values)

        else:
            print("File contains no azimuth noise blocks.")

        if False:
            import matplotlib.pyplot as plt
            plt.figure()
            plt.imshow(data)
            plt.colorbar()
            plt.show()

        return

    def extractImage(self, parse=False, removeNoise=False):
        """
           Use gdal python bindings to extract image
        """
        try:
            from osgeo import gdal
        except ImportError:
            raise Exception('GDAL python bindings not found. Need this for RSAT2/ TandemX / Sentinel1.')

        from scipy.interpolate import interp1d

        if parse:
            self.parse()

        print('Extracting normalized image ....')

        src = gdal.Open('/vsizip//'+self.tiff.strip(), gdal.GA_ReadOnly)
        band = src.GetRasterBand(1)

        if self.product.numberOfSamples != src.RasterXSize:
            raise Exception('Width in metadata and image dont match')

        if self.product.numberOfLines != src.RasterYSize:
            raise Exception('Length in metadata and image dont match')

        noiseFactor = 0.0
        if (not removeNoise) and self.noiseCorrectionApplied:
            print('User asked for data without noise corrections, but product appears to be corrected. Adding back noise from LUT ....')
            noiseFactor = 1.0
        elif removeNoise and (not self.noiseCorrectionApplied):
            print('User asked for data with noise corrections, but the products appears to not be corrected. Applying noise corrections from LUT ....')
            noiseFactor = -1.0
        elif (not removeNoise) and (not self.noiseCorrectionApplied):
            print('User asked for data without noise corrections. The product contains uncorrected data ... unpacking ....')
        else:
            print('User asked for noise corrected data and the product appears to be noise corrected .... unpacking ....')

        ###Write original SLC to file
        fid = open(self.output, 'wb')
        pix = np.arange(self.product.numberOfSamples)

        if self.noiseAzimuthLUT is not None:
            noise_azimuth_lut_indices, noise_azimuth_lut_values = self.noiseAzimuthLUT

        for ii in range(self.product.numberOfLines//100 + 1):
            ymin = int(ii*100)
            ymax = int(np.clip(ymin+100,0, self.product.numberOfLines))

            if ymax == ymin:
                break

            lin = np.arange(ymin,ymax)
            ####Read in one block of data
            data = 1.0 * band.ReadAsArray(0, ymin, self.product.numberOfSamples, ymax-ymin)

            lut = self.betaLUT(lin,pix,grid=True)

            if noiseFactor != 0.0:
                noise = self.noiseRangeLUT(lin)
                if self.noiseAzimuthLUT is not None:
                    block_azimuth_noise = np.zeros_like(noise)
                    for l_i, line in enumerate(lin):
                        interpolator = interp1d(noise_azimuth_lut_indices[line], noise_azimuth_lut_values[line], kind='previous', fill_value="extrapolate")
                        block_azimuth_noise[l_i] = interpolator(np.arange(self.product.numberOfSamples))
                    noise *= block_azimuth_noise
            else:
                noise = 0.0

            #outdata = data
            outdata = np.clip(data*data/(lut*lut) + noiseFactor * noise/(lut*lut), 0, None)
            #outdata = 10 * np.log10(outdata)

            outdata.astype(np.float32).tofile(fid)

        fid.close()

        ####Render ISCE XML
        slcImage = isceobj.createImage()
        slcImage.setByteOrder('l')
        slcImage.dataType = 'FLOAT'
        slcImage.setFilename(self.output)
        slcImage.setAccessMode('read')
        slcImage.setWidth(self.product.numberOfSamples)
        slcImage.setLength(self.product.numberOfLines)
        slcImage.renderHdr()
        slcImage.renderVRT()
        self.product.image = slcImage

        band = None
        src = None

        return

    def extractSlantRange(self, full=True):
        '''
        Extract pixel-by-pixel slant range file for GRD images.
        '''

        print('Extracing slant range ....')
        from scipy.interpolate import interp1d
        from isceobj.Util import Poly1D

        node = self._xml_root.find('coordinateConversion/coordinateConversionList')
        num = int(node.attrib['count'])

        lines = []
        data = []

        for ii, child in enumerate(node):
            t0 = self.convertToDateTime(child.find('azimuthTime').text)

            lines.append( (t0-self.product.sensingStart).total_seconds()/self.product.azimuthTimeInterval)

            pp =  [float(x) for x in child.find('grsrCoefficients').text.split()]

            meangr = float( child.find('gr0').text)
            if meangr !=0 :
                raise Exception('Ground range image does not start at zero coordinate')

            data.append(pp[::-1])

        ###If polynomial starts beyond first line
        if lines[0] > 0:
            lines.insert(0, 0.)
            pp = data[0]
            data.insert(0,pp)

        ####If polynomial ends before last line
        if lines[-1] < (self.product.numberOfLines-1):
            lines.append(self.product.numberOfLines-1.0)
            pp = data[-1]
            data.append(pp)

        lines = np.array(lines)
        data = np.array(data)

        LUT = []

        for ii in range(data.shape[1]):
            col = data[:,ii]
            LUT.append(interp1d(lines, col, bounds_error=False, assume_sorted=True))

        self.gr2srLUT = LUT

        ###Write original SLC to file
        fid = open(self.slantRangeFile, 'wb')
        pix = np.arange(self.product.numberOfSamples) * self.product.groundRangePixelSize
        lin = np.arange(self.product.numberOfLines)

        polys = np.zeros((self.product.numberOfLines, len(self.gr2srLUT)))

        for ii, intp in enumerate(self.gr2srLUT):
            polys[:,ii] = intp(lin)

        minrng = 1e11
        maxrng = -1e11

        for ii in range(self.product.numberOfLines):
            pp = polys[ii,:]
            outdata = np.polyval(pp, pix)
            minrng = min(minrng, outdata[0])   ###Can be made more efficient
            maxrng = max(maxrng, outdata[-1])

            outdata.tofile(fid)

        fid.close()

        self.product.startingSlantRange = minrng
        self.product.endingSlantRange = maxrng

        ####Render ISCE XML
        slcImage = isceobj.createImage()
        slcImage.setByteOrder('l')
        slcImage.dataType = 'DOUBLE'
        slcImage.setFilename(self.slantRangeFile)
        slcImage.setAccessMode('read')
        slcImage.setWidth(self.product.numberOfSamples)
        slcImage.setLength(self.product.numberOfLines)
        slcImage.renderHdr()
        slcImage.renderVRT()
        self.product.slantRangeImage = slcImage


from funciones import *
mayor=0
numero = int(input("numero primo: "))
while primo (numero):
    print("suma de los diguitos: ",sumadiguito(numero))
    diguito= int(input("diguito. "))
    print("el",diguito,"aparece", frecuencia(numero,diguito),"veces")
    if numero > mayor :
        mayor = numero
    numero =int(input("numero primo: "))
print("factorial de",mayor,":",factorial(mayor))


'''
Search currently highlighted text
'''
import webbrowser
base = "http://www.google.com/search?q="
phrase = clipboard.get_selection()

# Remove trailing or leading white space and find if there are multiple words.
phrase = phrase.strip()
search_url = base + phrase


import numpy as np

def local_energy(sample, n_site, t, U, net, state):

    st = np.zeros((sample, n_site, 2, n_site))
    st += state.num.reshape(sample, 1, 1, n_site)
    for i in range(sample):
        for j in range(n_site):
            if state.num[i][j] > 0:
                st[i][j][0][j] -= 1
                st[i][j][0][(j+1)%n_site] += 1
                st[i][j][1][j] -= 1
                st[i][j][1][(j-1+n_site)%n_site] += 1
    st = st.reshape(sample * n_site * 2, n_site)

    log_psi2 = net.output(st).reshape(sample, n_site, 2)

    eloc = np.zeros(sample)
    for i in range(sample):
        onsite = hopping = 0
        for j in range(n_site):
            if state.num[i][j] > 0:
                hopping += -1.0 * t * np.sqrt(state.num[i][j]
                                       * (state.num[i][(j+1)%n_site] + 1)) \
                    * np.exp(log_psi2[i][j][0] - state.log_psi[i])
                hopping += -1.0 * t * np.sqrt(state.num[i][j]
                                       * (state.num[i][(j-1+n_site)%n_site] + 1)) \
                    * np.exp(log_psi2[i][j][1] - state.log_psi[i])
                onsite += 0.5 * U * state.num[i][j] * (state.num[i][j] - 1)
        eloc[i] = hopping + onsite
    eloc = eloc.reshape([sample, 1])
    return eloc


import csv

csvFile = open('/Users/wei-chunhung/Desktop/Ettoday_webScraping.csv','w+', newline='')

try:
    writer = csv.writer(csvFile)
    writer.writerow(('Category','Product','Quantity'))
    writer.writerow(('iPhone','iPhone 12','20'))
finally:
    csvFile.close()


from sklearn.model_selection import train_test_split
from sklearn.utils import indexable

def split_train_test(X, y, test_size=0.2):
    """Split a dataset into train and test sets.

    Args:
        X (np.array or pd.DataFrame): Features.
        y (np.array or pd.DataFrame): Labels.
        test_size (float): Percentage in the test set.

    Returns:
        list: List with the dataset splitted (X_train, X_test, y_train, y_test).

    Examples:
        >>> X = np.random.randint(0,10, (100,5))
        >>> y = np.random.randint(0,1, 100)
        >>> X_train, X_test, y_train, y_test = split_train_test(X, y, test_size=0.2)
        >>> print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
        (80, 5) (20, 5) (80,) (20,)
    """
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=test_size, random_state=42, stratify=y
    )
    return X_train, X_test, y_train, y_test

def split_train_val_test(*arrays, val_size=0.2, test_size=0.2, random_seed=42):
    """Split a dataset into train, validation and test sets.

    Args:
        *arrays (list, np.array, pd.DataFrame): Dataset to split, it can be one or two objects with the same number of
                                                rows.
        val_size (float): Percentage in the validation set.
        test_size (float): Percentage in the test set.
        random_seed (float): Seed.

    Returns:
        list: List with the dataset splitted. If the input is one element `X`, the output will be
            `X_train, X_val, X_test`. If the input is two elements `X,y`, the output will be
            `X_train, X_val, X_test, y_train, y_val, y_test`.

    Examples:
        >>> X = np.random.randint(0,10, (100,5))
        >>> y = np.random.randint(0,1, 100)
        >>> X_train, X_val, X_test, y_train, y_val, y_test = split_train_val_test(X, y, val_size=0.2, test_size=0.2)
        >>> print(X_train.shape, X_val.shape, X_test.shape)
        (60, 5) (20, 5) (20, 5)
        >>> print(y_train.shape, y_val.shape, y_test.shape)
        (60,) (20,) (20,)
        >>> df = pd.DataFrame(np.random.randn(100, 5), columns=list('ABCDE'))
        >>> df_train, df_val, df_test = split_train_val_test(df, val_size=0.2, test_size=0.2)
        >>> print(df_train.shape, df_val.shape, df_test.shape)
        (60, 5) (20, 5) (20, 5)
    """
    n_arrays = len(arrays)
    if n_arrays == 1:
        X_train, X_test = train_test_split(
            *arrays, test_size=test_size, random_state=random_seed
        )
        X_train, X_val = train_test_split(
            X_train, test_size=val_size / (1 - test_size), random_state=random_seed
        )
        return X_train, X_val, X_test
    elif n_arrays == 2:
        X, y = indexable(*arrays)
        X_train, X_test, y_train, y_test = train_test_split(
            X, y, test_size=test_size, random_state=random_seed, stratify=y
        )
        X_train, X_val, y_train, y_val = train_test_split(
            X_train,
            y_train,
            test_size=val_size / (1 - test_size),
            random_state=random_seed,
            stratify=y_train,
        )
        return X_train, X_val, X_test, y_train, y_val, y_test
    else:
        raise ValueError("Wrong number of inputs")


#Exercise 2: This program counts the distribution of the hour of the day
#for each of the messages. You can pull the hour from the “From” line
#by finding the time string and then splitting that string into parts using
#the colon character. Once you have accumulated the counts for each
#hour, print out the counts, one per line, sorted by hour as shown below.
#python timeofday.py
#Enter a file name: mbox-short.txt
#04 3
#06 1
#07 1
#09 2
#10 3
#11 6
#14 1
#15 2
#16 4
#17 2
#18 1
#19 1

filename=input("enter a file name: ")
fhand=open(filename)
days={}
for line in fhand:
    if line.startswith("From "):
        day=line.split()[5]
        m=day.split(":")[0]
        days[m]=days.get(m,0)+1

list=[]
for key,value in days.items():
    list.append((key,value))
list.sort()
for l in list:
    print(l[0],l[1])


from typing import Tuple

import numpy as np #type: ignore

import colors

# Tile graphics structured type compatible with Console.tiles_rgb
graphic_dt = np.dtype(
    [("ch",np.int32), # Unicode codepoint,
     ("fg", "3B"),    # 3 unsigned bytes, for RGB colors
     ("bg","3B"),
    ]
)

# Tile struct used for statically defined tile data.
# (First notable departure from tutorial: I still plan to draw unseen tiles,
#  albeit black on black, because I want to use the character data from the
#  console for some git commands. Maybe there's a nicer way to do this, but
#  I'm too lazy to think about it atm.)
tile_dt = np.dtype(
    [("walkable",np.bool),    # True if can be walked over
     ("transparent",np.bool), # True if can be seen through
     ("dark",graphic_dt),     # graphics for when not in FOV
     ("light",graphic_dt),    # graphics for when in FOV
     ("unseen",graphic_dt),   # graphics for when unexplored
     ("name_index",np.int32), # index into list of tile names
    ]
)

def new_tile(
        *, # Enforce use of keywords
        walkable: int, transparent: int,
        dark: Tuple[int,Tuple[int,int,int],Tuple[int,int,int]],
        light: Tuple[int,Tuple[int,int,int],Tuple[int,int,int]],
        name:str,
        ) -> np.ndarray:
    # Automatically generate the "unseen" graphic
    """Helper for defining individual tile types."""
    unseen = (dark[0],colors.default_bg,colors.default_bg)
    # Possibly useful when designing UI (makes map boundary visible):
    #unseen = (dark[0],colors.test_bg,colors.test_bg)
    return np.array((walkable,transparent,dark,light,unseen,name),dtype=tile_dt)

# Define tiles here =========================
# (I know this is annoying, but the reason for this list is so that the
#  name can be stored as an int in the tile array, for numpy reasons)
tile_names = [
    "floor",
    "wall",
    "stairs (down)",
    "stairs (up)",
    "water",
]
floor = new_tile(
    walkable=True, transparent=True,
    dark=(ord(" "),colors.default_dim_fg,colors.default_bg),
    light=(ord(" "),colors.default_fg,colors.default_FOV_bg),
    name=tile_names.index("floor"),
)
wall = new_tile(
    walkable=False, transparent=False,
    dark=(ord("#"),colors.default_dim_fg,colors.default_bg),
    light=(ord("#"),colors.default_fg,colors.default_FOV_bg),
    name=tile_names.index("wall"),
)
water = new_tile(
    walkable=False, transparent=True,
    dark=(ord("~"),colors.water_dim_fg,colors.default_bg),
    light=(ord("~"),colors.water_fg,colors.default_FOV_bg),
    name=tile_names.index("water"),
)
down_stairs = new_tile(
    walkable=True, transparent=True,
    dark=(ord(">"),colors.default_dim_fg,colors.default_bg),
    light=(ord(">"),colors.default_fg,colors.default_FOV_bg),
    name=tile_names.index("stairs (down)"),
)
up_stairs = new_tile(
    walkable=True, transparent=True,
    dark=(ord("<"),colors.default_dim_fg,colors.default_bg),
    light=(ord("<"),colors.default_fg,colors.default_FOV_bg),
    name=tile_names.index("stairs (up)"),
)
tile_names = np.array(tile_names) # To support fancy indexing


class Calculator:
    def __init__(self):
        # Inițializăm valoarea curentă a calculatorului și listele pentru istoric și viitor
        self.current_value = 0
        self.history = []
        self.future = []

    def handle_operation(self, operator, value):
        # Manipulează operațiile și valorile corespunzătoare și adaugă la istoricul valorii curente
        if operator == '+':
            self.history.append(self.current_value)
            self.current_value += value
            self.future = []  # Curăță lista pentru viitor
        elif operator == '-':
            self.history.append(self.current_value)
            self.current_value -= value
            self.future = []
        elif operator == '*':
            self.history.append(self.current_value)
            self.current_value *= value
            self.future = []
        elif operator == '/':
            self.history.append(self.current_value)
            self.current_value /= value
            self.future = []

    def undo(self):
        # Întoarce ultima valoare din istoric și adaugă valoarea actuală la viitor
        if self.history:
            self.future.append(self.current_value)
            self.current_value = self.history.pop()

    def redo(self):
        # Reface ultima valoare din viitor și adaugă valoarea actuală la istoric
        if self.future:
            self.history.append(self.current_value)
            self.current_value = self.future.pop()

if __name__ == '__main__':
    calc = Calculator()
    print("Calculator is on. Available operations: '+', '-', '*', '/', 'undo', 'redo', 'exit'.")

    while True:
        user_input = input("Enter operation: ")
        if user_input == 'exit':
            print("Exiting calculator.")
            break

        if user_input in ['+', '-', '*', '/']:
            operator = user_input
            value = float(input("Enter value: "))
            calc.handle_operation(operator, value)
            print("Current value:", calc.current_value)

        elif user_input == 'undo':
            calc.undo()
            print("After undoing:", calc.current_value)

        elif user_input == 'redo':
            calc.redo()
            print("After redoing:", calc.current_value)

        else:
            print("Invalid operation. Please try again.")

Tema Adapter, Bridge si Proxy/Calculator.py


def getDialog():
	class Dialog(QtGui.QWidget):
		buttonClicked = QtCore.pyqtSignal()
		def __init__(self, imagePath, text, redText=False, *args, **kwargs):
			super(Dialog, self).__init__(*args, **kwargs)

			frame = QtGui.QFrame()
			frame.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised)
			frame.setMidLineWidth(2)
			frame.setLineWidth(3)

			frameLayout = QtGui.QHBoxLayout()
			frameLayout.setAlignment(QtCore.Qt.AlignHCenter)

			imageLabel = QtGui.QLabel("<img src=\"" + imagePath + "\" />")
			imageLabel.setAlignment(QtCore.Qt.AlignHCenter)
			frameLayout.addWidget(imageLabel)

			textLabel = QtGui.QLabel(text)
			textLabel.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
			textLabel.setWordWrap(True)
			textLabel.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
			if redText:
				textLabel.setStyleSheet("color: #b60000; font-weight: bold;")
			else:
				textLabel.setStyleSheet("font-weight: bold;")
			frameLayout.addWidget(textLabel)

			backButton = QtGui.QPushButton("Close")
			backButton.clicked.connect(lambda: self.buttonClicked.emit())
			frameLayout.addWidget(backButton)

			frame.setLayout(frameLayout)

			layout = QtGui.QHBoxLayout()
			layout.addWidget(frame)
			self.setLayout(layout)
	return Dialog

def getBigDialog():
	class BigDialog(QtGui.QWidget):
		def __init__(self, imagePath, text, *args, **kwargs):
			super(BigDialog, self).__init__(*args, **kwargs)

			layout = QtGui.QVBoxLayout()

			image = QtGui.QPixmap(imagePath)
			imageLabel = QtGui.QLabel()
			imageLabel.setPixmap(image)
			imageLabel.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
			layout.addWidget(imageLabel)

			textLabel = QtGui.QLabel(text)
			textLabel.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop)
			textLabel.setWordWrap(True)
			textLabel.setStyleSheet("font-size: 18px; font-weight: bold;")
			layout.addWidget(textLabel)

			self.setLayout(layout)
	return BigDialog

class DialogShower(object):
	def __init__(self, logoImagePath, brokenImagePath, bigLogoImagePath, bigBrokenImagePath, uiModule, *args, **kwargs):
		super(DialogShower, self).__init__(*args, **kwargs)

		self.logoImagePath = logoImagePath
		self.brokenImagePath = brokenImagePath
		self.bigLogoImagePath = bigLogoImagePath
		self.bigBrokenImagePath = bigBrokenImagePath

		self.uiModule = uiModule

	def showError(self, tab, text):
		dialog = Dialog(self.brokenImagePath, text, True)
		self.showDialog(tab, dialog)

	def showMessage(self, tab, text):
		dialog = Dialog(self.logoImagePath, text)
		self.showDialog(tab, dialog)

	def showBigMessage(self, text):
		dialog = BigDialog(self.bigLogoImagePath, text)
		self.showBigDialog(dialog)

	def showBigError(self, text):
		dialog = BigDialog(self.bigBrokenImagePath, text)
		self.showBigDialog(dialog)

	def showBigDialog(self, dialog):
		tab = self.uiModule.addCustomTab(dialog, previousTabOnClose=True)
		tab.closeRequested.handle(tab.close)

	def showDialog(self, tab, dialog):
		tabLayout = tab.wrapperWidget.layout()

		# First, remove all other errors if any are there
		for i in xrange(tabLayout.count() - 1):
			it = tabLayout.itemAt(i)
			w = tabLayout.itemAt(i).widget()
			if isinstance(w, Dialog):
				# Old error is still there, remove it.
				tabLayout.removeItem(it)
				w.setParent(None)

		# What happens when you click the button on the dialog
		def removeWidget():
			tabLayout.removeWidget(dialog)
			dialog.setParent(None)

		dialog.buttonClicked.connect(removeWidget)

		tabLayout.insertWidget(0, dialog)

class DialogShowerModule(object):
	"""This module allows to show a message in a in the main window
	   embedded dialog.

	   To do that, you need to call .send() on one of the events defined
	   in this class. The arguments are the tab on which it needs to be
	   shown, and the text of the message.

	"""
	def __init__(self, moduleManager, *args, **kwargs):
		super(DialogShowerModule, self).__init__(*args, **kwargs)
		self._mm = moduleManager

		self.type = "dialogShower"

		self.requires = (
			self._mm.mods(type="ui"),
			self._mm.mods(type="event"),
		)

	def enable(self):
		global QtCore, QtGui
		try:
			from PyQt4 import QtCore, QtGui
		except ImportError:
			return
		global Dialog, BigDialog
		Dialog = getDialog()
		BigDialog = getBigDialog()
		self._modules = set(self._mm.mods(type="modules")).pop()

		_event = self._modules.default(type="event")

		logoImagePath = self._mm.resourcePath("images/ot240.png")
		brokenImagePath = self._mm.resourcePath("images/otbroken240.png")
		bigLogoImagePath = self._mm.resourcePath("images/ot2300.png")
		bigBrokenImagePath = self._mm.resourcePath("images/otbroken2300.png")

		uiModule = self._modules.default("active", type="ui")

		self.dialogShower = DialogShower(logoImagePath, brokenImagePath, bigLogoImagePath, bigBrokenImagePath, uiModule)

		self.showError = _event.createEvent()
		self.showMessage = _event.createEvent()
		self.showBigMessage = _event.createEvent()
		self.showBigError = _event.createEvent()
		self.showBigDialog = _event.createEvent()
		self.showDialog = _event.createEvent()

		self.showError.handle(self.dialogShower.showError)
		self.showMessage.handle(self.dialogShower.showMessage)
		self.showBigMessage.handle(self.dialogShower.showBigMessage)
		self.showBigError.handle(self.dialogShower.showBigError)
		self.showBigDialog.handle(self.dialogShower.showBigDialog)
		self.showDialog.handle(self.dialogShower.showDialog)

		self.active = True

	def disable(self):
		self.active = False

		del self.dialogShower

		del self.showError
		del self.showMessage
		del self.showBigMessage
		del self.showBigError
		del self.showBigDialog
		del self.showDialog

		del self._modules

def init(moduleManager):
	return DialogShowerModule(moduleManager)


# -*- coding: utf-8 -*-
"""
Created using prof's notes in Tuesday 12/6 class

@author: jjser
"""

import numpy as np
import matplotlib.pyplot as plt
import math

#### Initializing Everything
# Parameters
ni = 56 # number of cells in i
nj = 2 # number of cells in j
g = 1 # number of ghost cells
#dxi =  (4.5-0) / (ni-1)
#deta = (1-0) / (nj-1)
dxi =  (4.5-0) / (ni-1)
deta = (1-0) / (nj-1)
dt = 0.032

# Grid
eta = np.zeros((ni+2*g,nj+2*g))
xi = np.zeros((ni+2*g,nj+2*g))
x = np.zeros((ni+2*g,nj+2*g))
y = np.zeros((ni+2*g,nj+2*g))

# Fluid Quantities
u = np.zeros((ni+2*g,nj+2*g,4))
ruvp = np.zeros((ni+2*g,nj+2*g,4)) # rho, u, v and pressure

# Derivatives and Jacobian
dxidx = np.zeros((ni+2*g,nj+2*g))
dxidy = np.zeros((ni+2*g,nj+2*g))
detadx = np.zeros((ni+2*g,nj+2*g))
detady = np.zeros((ni+2*g,nj+2*g))
Jdet = np.zeros((ni+2*g,nj+2*g))

# RHS
rhs = np.zeros((ni+2*g,nj+2*g))

#### Initializing the Grid
# Notes: ghost cells are treated as 0 index

ib = g
jb = g
ie = ib + ni - 1
je = jb + nj - 1
# Set Initial Condition
for i in np.arange(ib,ie+1): # goes from ib to ie
    for j in np.arange(jb,je+1): # goes from jb to je
        xi[i,j] = (i-ib) * (4.5-0) / (ni-1) + 0
        eta[i,j] = (j-jb) * (1-0) / (nj-1) + 0
for i in np.arange(ib,ie+1): # goes from ib to ie
    for j in np.arange(jb,je+1): # goes from jb to je
        x[i,j] = xi[i,j]
        y[i,j] = eta[i,j]

#### Calculating Derivatives and Jacobian
for i in np.arange(ib,ie):
    for j in np.arange(jb,je):
        if i >=2 and i<= ni-1:
            # central
            dx_dxi = (x[i+1,j]-x[i-1,j]) / (2 * dxi)
            dy_dxi = (y[i+1,j]-y[i-1,j]) / (2 * dxi)
        elif i == 1:
            # forward
            dx_dxi = (x[i+1,j]-x[i,j]) / (dxi)
            dy_dxi = (y[i+1,j]-y[i,j]) / (dxi)
        elif i == ni:
            # forward
            dx_dxi = (x[i,j]-x[i-1,j]) / (dxi)
            dy_dxi = (y[i,j]-y[i-1,j]) / (dxi)

        if j >=2 and j<= nj-1:
            # central
            dx_deta = (x[i,j+1]-x[i,j-1]) / (2 * deta)
            dy_deta = (y[i,j+1]-y[i,j-1]) / (2 * deta)
        elif j == 1:
            # forward
            dx_deta = (x[i,j+1]-x[i,j]) / (deta)
            dy_deta = (y[i,j+1]-y[i,j]) / (deta)
        elif j == nj:
            # forward
            dx_deta = (x[i,j]-x[i,j-1]) / (deta)
            dy_deta = (y[i,j]-y[i,j-1]) / (deta)
        Jdet[i,j] = 1/(dx_dxi*dy_deta-dx_deta*dy_dxi)
        dxidx[i,j] = dy_deta * Jdet[i,j]
        dxidy[i,j] = -dx_deta * Jdet[i,j]
        detadx[i,j] = -dy_dxi * Jdet[i,j]
        detady[i,j] = dx_dxi * Jdet[i,j]

#### Initial Condition
# Set Initial Condition
ga = 1.4
r0 = 1.0
rf = 0.125
u0 = 0.0
v0 = 0.0
p0 = 1.0/ ga
pf = 10.0 * p0
c = 1
for i in np.arange(ib,ie+1): # goes from ib to ie
    for j in np.arange(jb,je+1): # goes from jb to je
        u[i,j,1] = r0 * u0
        u[i,j,2] = r0 * v0

        ruvp[i,j,0] = u[i,j,0]
        ruvp[i,j,1] = u[i,j,1] / u[i,j,0]
        ruvp[i,j,2] = u[i,j,2] / u[i,j,0]
        q = 0.5 * (ruvp[i,j,1]**2 + ruvp[i,j,2]**2)

        E0 = r0*q + p0/(ga-1)
        Ef = rf*q + pf/(ga-1)

        if i*dxi >= 1.95:
            u[i,j,0] = r0
            u[i,j,3] = E0
        else:
            u[i,j,0] = rf
            u[i,j,3] = Ef

        ruvp[i,j,3] = (u[i,j,3] - u[i,j,0] * q)*(ga-1)

#### Boundary Conditions
# tbh idk

#### Functions for upwinding
# Eigenvalues

ruvp[i,j,0] = u[i,j,0]
ruvp[i,j,1] = u[i,j,1] / u[i,j,0]
ruvp[i,j,2] = u[i,j,2] / u[i,j,0]
q = 0.5 * (ruvp[i,j,1]**2 + ruvp[i,j,2]**2)
ruvp[i,j,3] = (u[i,j,3] - u[i,j,0] * q)*(ga-1)

l1 = dxidx[i,j] * ruvp[i,j,1] + dxidy[i,j] * ruvp[i,j,2]
l2 = l1
l3 = l1 + c * math.sqrt(l1**2+l2**2)
l4 = l1 - c * math.sqrt(l1**2+l2**2)
# F and G plus and minus
def FGpm(l1,l2,l3,l4,u,v,k1,k2):
    k1b = k1/math.sqrt(k1**2+k2**2)
    k2b = k2/math.sqrt(k1**2+k2**2)
    FGpm = np.zeros(4)
    FGpm[0] = 2*(ga-1)*l1 + l3 + l4
    FGpm[1] = 2*(ga-1)*l1*u + l3*(u+c*k1b) + l4*(u-c*k1b)
    FGpm[2] = 2*(ga-1)*l1*v + l3*(u+c*k2b) + l4*(u-c*k2b)
    W = ((3-ga)*(l3+l4)*c**2)/(2*(ga-1))
    FGpm[3] = (ga-1)*l1*(u**2+v**2) + 0.5*l3*((u+c*k1b)**2+(v+c*k2b)**2) + 0.5*l4*((u-c*k1b)**2+(v-c*k2b)**2) + W

def computelambdas(i,j):
    u = ruvp[i,j,1]
    v = ruvp[i,j,2]
    l1 = dxidx[i,j] * ruvp[i,j,1] + dxidy[i,j] * ruvp[i,j,2]
    l2 = l1
    l3 = l1 + c * math.sqrt(l1**2+l2**2)
    l4 = l1 - c * math.sqrt(l1**2+l2**2)
    return l1, l2, l3, l4

def getuv(i,j):
    u = u[i,j,1]
    v = u[i,j,2]
    return u,v

def lpm(l):
    ep = 0.01
    lp = 0.5 * (l + math.sqrt(l**2 + ep ** 2))
    lm = 0.5 * (l + math.sqrt(l**2 + ep ** 2))
    return lp, lm

def bound():
    pass

#### Solver, residual
t = 0
tf = 1.0
while t <= tf:
    t += dt
    bound()
    rhoold = u[i,j,0]
    for i in np.arange(ib,ie):
        for j in np.arange(jb,je):
            # Do Explicit Euler to find update u vector
            rhs = np.zeros(4)
            # what is u and v here for now?
            #rhs = FGpm(l1,l2,l3,l4,u,v,1,0) # generic F and G
            # set l1,l2,l3 and l4, u and v
            l1,l2,l3,l4,u,v = computelambdas(i,j)
            rhs += FGpm(l1,l2,l3,l4,u,v,1,0) # Fplus
            l1,l2,l3,l4,u,v = computelambdas(i-1,j)
            rhs -= FGpm(l1,l2,l3,l4,u,v,1,0) # Fplus
            l1,l2,l3,l4,u,v = computelambdas(i+1,j)
            rhs += FGpm(l1,l2,l3,l4,u,v,1,0) # Fminus
            l1,l2,l3,l4,u,v = computelambdas(i,j)
            rhs -= FGpm(l1,l2,l3,l4,u,v,1,0) # Fminus
            l1,l2,l3,l4,u,v = computelambdas(i,j)
            rhs += FGpm(l1,l2,l3,l4,u,v,0,1) # Gplus
            l1,l2,l3,l4,u,v = computelambdas(i,j-1)
            rhs -= FGpm(l1,l2,l3,l4,u,v,0,1) # Gplus
            l1,l2,l3,l4,u,v = computelambdas(i,j+1)
            rhs += FGpm(l1,l2,l3,l4,u,v,0,1) # Gminus
            l1,l2,l3,l4,u,v = computelambdas(i,j)
            rhs -= FGpm(l1,l2,l3,l4,u,v,0,1) # Gminus
            u[i,j] += rhs * dt * Jdet[i,j]

            # Store rho, uvel, vvel, pres from u vector
            ruvp[i,j,0] = u[i,j,0]
            ruvp[i,j,1] = u[i,j,1] / u[i,j,0]
            ruvp[i,j,2] = u[i,j,2] / u[i,j,0]
            q = 0.5 * (ruvp[i,j,1]**2 + ruvp[i,j,2]**2)
            ruvp[i,j,3] = (u[i,j,3] - u[i,j,0] * q)*(ga-1)

    # Compute Residual
    res = 0
    for i in np.arange(ib,ie):
        for j in np.arange(jb,je):
            res += (ruvp[i,j,0]-rhoold[i,j])**2
    res = math.sqrt(res / ((ni-2)*(nj-2)) )

print('Solution Solved lmao')
print('Final time at', str(t))

#### Post-processing, plotting contours
# Computing rho, u vel, v vel, vel mag and pressure
rho = np.zeros((ni+2*g,nj+2*g))
uvel = np.zeros((ni+2*g,nj+2*g))
vvel = np.zeros((ni+2*g,nj+2*g))
velmag = np.zeros((ni+2*g,nj+2*g))
pres = np.zeros((ni+2*g,nj+2*g))
for i in np.arange(ib,ie+1): # goes from ib to ie
    for j in np.arange(jb,je+1): # goes from jb to je
        rho[i,j] = u[i,j,0]
        uvel[i,j] = u[i,j,1] / u[i,j,0]
        vvel[i,j] = u[i,j,2] / u[i,j,0]
        velmag[i,j] = math.sqrt(uvel[i,j]**2 + vvel[i,j]**2)
        quack = 0.5 * rho[i,j] * (uvel[i,j]**2 + vvel[i,j]**2)
        vvel[i,j] = ( u[i,j,3] - quack ) * (ga-1)

# Plot of density distribution distribution inside the shock tube
fig, ax = plt.subplots()
ax.set_title('rho/rho0 vs x')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_xlim([0,4.5])
ax.set_ylim([0,1.25])
ax.plot(x[ib:ie+1,je], rho[ib:ie+1,je],'bo')

# Contour Plot of Jacobian
fig, ax = plt.subplots()
cf = ax.contourf(x[ib:ie+1,jb:je+1], y[ib:ie+1,jb:je+1], Jdet[ib:ie+1,jb:je+1])
cbar = fig.colorbar(cf)
plt.show()  # Jdet.min() = -1, Jdet.max() = 0

'''
def main():
    grid()

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


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Aaron LI
# Created: 2016-01-16
# Updated: 2016-01-16
#

"""
Clean the lightcurve by fitting the RATE data with a Gaussian model,
and discard the time bins with RATE beyond [mean-n*sigma, mean+n*sigma].
"""

__version__ = "0.1.0"
__date__ = "2016-01-16"

import sys
import argparse

from astropy.io import fits
import numpy as np

class LightCurve:
    """
    X-ray data light curve class
    """
    def __init__(self, lcfile):
        f = fits.open(lcfile)
        self.lc_data = f[1].data
        self.lc_header = f[1].header
        self.time     = self.lc_data['TIME']
        self.rate     = self.lc_data['RATE']
        self.rate_err = self.lc_data['ERROR']
        self.TSTART   = self.lc_header['TSTART']
        self.TSTOP    = self.lc_header['TSTOP']
        self.TIMEDEL  = self.lc_header['TIMEDEL']
        self.TIMEPIXR = self.lc_header['TIMEPIXR']
        f.close()

    def sigma_clip(self, nsigma=3, maxiter=10):
        """
        Iteratively clip the time bins whose value lie beyond the
        range [mean-n*sigma, mean+n*sigma].
        """
        rate = self.rate
        keep_idx = np.ones(rate.shape, dtype=bool)  # all True's
        keep_num = np.sum(keep_idx)
        keep_num0 = np.inf
        i = 0
        while (keep_num < keep_num0):
            if (i >= maxiter):
                print("WARNING: maximum iteration limit reached",
                        file=sys.stderr)
                break
            keep_num0 = keep_num
            i += 1
            mean  = np.mean(rate[keep_idx])
            sigma = np.std(rate[keep_idx])
            cut_low  = mean - nsigma * sigma
            cut_high = mean + nsigma * sigma
            keep_idx = np.logical_and((rate >= cut_low), (rate <= cut_high))
            keep_num = np.sum(keep_idx)
        # save clip results
        self.niter = i
        self.keep_idx = keep_idx
        self.time_clipped = self.time[keep_idx]
        self.rate_clipped = self.rate[keep_idx]

    def make_gti(self, apply_header=True):
        """
        Make new GTIs (good time intervals) according to the clipped
        time bins.
        """
        frac = 0.01  # TIMEDEL fraction to distingush two time bins
        gti_start = []
        gti_stop  = []
        time_start = self.time_clipped
        time_stop  = time_start + self.TIMEDEL
        # first GTI start time
        gti_start.append(time_start[0])
        for tstart, tstop in zip(time_start[1:], time_stop[:-1]):
            if (np.abs(tstart-tstop) <= frac * self.TIMEDEL):
                # time bin continues
                continue
            else:
                # a new GTI start
                gti_start.append(tstart)
                gti_stop.append(tstop)
        # last GTI stop time
        gti_stop.append(time_stop[-1])
        # convert to numpy array
        gti_start = np.array(gti_start)
        gti_stop  = np.array(gti_stop)
        if apply_header:
            # add TSTART to the time
            gti_start += self.TSTART
            gti_stop  += self.TSTART
        # save results
        self.gti_start = gti_start
        self.gti_stop  = gti_stop

    def write_gti(self, filename=None, header=True):
        """
        Write generated GTIs to file or screen (default)
        """
        if isinstance(filename, str):
            outfile = open(filename, 'w')
        else:
            outfile = sys.stdout
        #
        if header:
            outfile.write('# TSTART\tTSTOP\n')
        outfile.write('\n'.join([ '%s\t%s' % (tstart, tstop) \
                for tstart, tstop in zip(self.gti_start, self.gti_stop) ]))
        #
        if isinstance(filename, str):
            outfile.close()

def main():
    parser = argparse.ArgumentParser(
            description="Clean light curve by sigma clipping")
    parser.add_argument("-V", "--version", action="version",
            version="%(prog)s " + "%s (%s)" % (__version__, __date__))
    parser.add_argument("infile",
            help="input lightcurve file; contains [TIME, RATE] columns")
    parser.add_argument("outfile", nargs='?', default=None,
            help="output text-format GTI file; for XSELECT filter time")
    parser.add_argument("-s", "--nsigma", dest="nsigma", type=float,
            default=2.0, help="sigma clipping significant level")
    parser.add_argument("-H", "--no-header", dest="noheader",
            action="store_true", help="not write header to the output file")
    parser.add_argument("-v", "--verbose", dest="verbose",
            action="store_true", help="show verbose information")
    args = parser.parse_args()

    lc = LightCurve(args.infile)
    lc.sigma_clip(nsigma=args.nsigma)
    lc.make_gti(apply_header=True)
    lc.write_gti(filename=args.outfile, header=(not args.noheader))
    if args.verbose:
        exposure = np.sum(lc.gti_stop - lc.gti_start)
        print("# Total GTI: %.2f (s)" % exposure)

if __name__ == "__main__":
    main()

#  vim: set ts=4 sw=4 tw=0 fenc=utf-8 ft=python: #


import random

def insert_sort(li):
    if len(li) < 2:
        return li
    else:
        for i in range(1, len(li)):
            j = i - 1
            temp = li[i]
            while j >= 0 and temp < li[j]:
                li[j+1] = li[j]
                j -= 1
            li[j+1] = temp

array = [i for i in range(10)]
print(array)
random.shuffle(array)
insert_sort(array)
print(array)


import cv2

video_stream = 0
threshold = 80
circle_radius = 325

def convert_frame_to_grayscale(frame):
    return cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

def calculate_variance_of_laplacian(grayscale_frame):
    return cv2.Laplacian(grayscale_frame, cv2.CV_64F).var()

def add_center_circle_to_window(grayscale_frame, original_frame, text_color):
    M = cv2.moments(grayscale_frame)
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])
    cv2.circle(original_frame, (cX, cY), circle_radius, text_color, 4)

def add_text_to_window(original_frame, display_text, text_color):
    cv2.putText(original_frame, display_text, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, text_color, 2)

def is_tire_in_focus():
    cap = cv2.VideoCapture(video_stream)
    while True:
        ret, original_frame = cap.read()

        if not ret:
            break

        grayscale_frame = convert_frame_to_grayscale(original_frame)
        variance = calculate_variance_of_laplacian(grayscale_frame)

        if variance > threshold:
            text_color = (0, 255, 0)
            display_text = 'Tire in focus'
        else:
            display_text = 'Tire is out of focus'
            text_color = (0, 0, 255)

        add_text_to_window(original_frame, display_text, text_color)
        add_center_circle_to_window(grayscale_frame, original_frame, text_color)
        cv2.imshow("LiveStream Video", original_frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

is_tire_in_focus()


from flask import jsonify, request, g
from app import app
from app.models import Category, Dish, Restaurant, Session, User
from app.models import db

@app.before_request
def save_location():
    if request.is_json:
        if 'latitude' in request.json and 'longitude' in request.json:
            g.latitude = request.json['latitude']
            g.longitude = request.json['longitude']
        if 'username' in request.json:
            g.username = request.json['username']

@app.route('/dishes', methods=['GET'])
def get_dishes():
    dishes = Dish.query.all()
    output = []
    for dish in dishes:
        output.append(dish.get_data())
    return jsonify(output)

@app.route('/dishes/<int:id>', methods=['GET'])
def get_dish(id):
    dish = Dish.query.get_or_404(id)
    return jsonify(dish.get_data())

@app.route('/restaurants', methods=['GET'])
def get_restaurants():
    restaurants = Restaurant.query.all()
    output = []
    for restaurant in restaurants:
        output.append(restaurant.get_data())
    return jsonify(output)

@app.route('/restaurants/<int:id>', methods=['GET'])
def get_restaurant(id):
    restaurant = Restaurant.query.get_or_404(id)
    return jsonify(restaurant.get_data())

@app.route('/restaurants/<int:id>/dishes', methods=['GET'])
def get_restaurant_dishes(id):
    restaurant = Restaurant.query.get_or_404(id)
    output = []
    for dish in restaurant.dishes:
        output.append(dish.get_data())
    return jsonify(output)

@app.route('/sessions/<int:session_id>/next_dish', methods=['GET'])
def next_dish(session_id):
    session = db.session.get(Session, session_id)
    if not session:
        session = Session(id=session_id)
        db.session.add(session)
        db.session.commit()
    dish = session.next_unrelated_dish()
    return jsonify(dish.get_data())

@app.route('/sessions/<int:session_id>/next_restaurant', methods=['GET'])
def next_restaurant(session_id):
    session = db.session.get(Session, session_id)
    if not session:
        session = Session(id=session_id)
        db.session.add(session)
        db.session.commit()
    restaurant = session.next_unrelated_restaurant()
    return jsonify(restaurant.get_data(with_dishes=False))

@app.route('/users', methods=['POST'])
def create_user():
    username = request.json.get('username')
    if not username:
        return jsonify({'error': 'Username is required'}), 400

    if User.query.filter_by(username=username).first():
        return jsonify({'error': 'Username already exists'}), 400

    user = User(username=username)
    db.session.add(user)
    db.session.commit()

    return jsonify({'message': 'User created successfully'}), 201

@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = User.query.get_or_404(user_id)
    return jsonify(user.get_data())

@app.route('/dishes/<int:dish_id>/like', methods=['POST'])
def like_dish(dish_id):
    dish = Dish.query.get_or_404(dish_id)
    if dish.like(username=request.json.get('username')):
        db.session.commit()
        return jsonify({'like': 1}), 200
    else:
        return jsonify({'like': 0}), 200

@app.route('/dishes/<int:dish_id>/comment', methods=['POST'])
def comment_dish(dish_id):
    dish = Dish.query.get_or_404(dish_id)
    dish.comment(username=request.json.get('username'), comment=request.json.get('comment'))
    db.session.commit()
    return jsonify({'message': 'Dish commented successfully'}), 200

@app.route('/categories', methods=['GET'])
def get_categories():
    categories = Category.query.all()
    output = []
    for category in categories:
        output.append(category.get_data(with_dishes=False, with_restaurants=False))
    return jsonify(output)