from __future__ import print_function
import acm
import types
from DealPackageDevKit import DealPackageDefinition, Object, Action, Str, Bool, CalcVal, List, CounterpartyChoices, AcquirerChoices
from DealPackageDevKit import PortfolioChoices, TradeStatusChoices, DealPackageChoiceListSource, DealPackageException, ParseFloat
from PairOptionsFormatters import GetFXSpotForwardFormatter, AmountFormatter, FXRateFormatter, FXRateInverseFormatter, FXPointsFormatter, SingleValueFormatter
from PairOptionsUtil import GetMaxMinBounderiesStrikeSolving, GuiAttributeToSolverAttributeName, GetOppositeAttributeName
from PairOptionsUtil import IsOfTypeFLot, IsFxOption, IsValidBidAskVolatilitySurfaces
from PairOptionsUtil import QuotationLabel, CurrencyLabel, GetFloatFromCalculation, GetFixingSourceChoices, GetValGroupChoices, Inverse
from PairOptionsUtil import ValuationAddOnModelIsUsed, ValuesAreEqual, PriceGreekExcludeVolatilityMovement, DomesticColumnConfig
from PairOptionsUtil import Flipped, IsBidAskValue, IsIterable, TransformDecimalPoints, TransformMagnitude
from PairOptionsUtil import CurrencyStrFromDV, UsePerUnitQuotationImpl
from PairOptionsUtil import FixingSourceFromString, ValGroupFromString
from InstrumentPairFromStrUtil import InstrumentFromStr, InstrumentPairFromStr, CallPutFromInstrumentPairFromStr, GetInstrumentPairFromInput
from DateFromStrUtil import TransformExpiryInputStrToDate
from OptionTypeFromStrUtil import TransformToOptionTypeFromStr
from DealPackageCalculations import DealPackageCalculations
from FXOptionPricerExtensionPoint import TurnOffRealTimeUpdatesOnSimulation, PreciousMetalChoiceList
from FXOptionPricerExtensionPoint import ValuationGroupOverride, CustomerAdditionalAttributes
from TraitBasedDealPackage import SetSolverParametersWithSafeExit
from FXCalculations import SaveTradeCalculations

class PairOptionsDealPackageBase(DealPackageDefinition):
    expiryDate =                Object( label='Expiry',
                                        objMapping='PricingInstruments.FxoExpiryDate',
                                        onChanged='@UnsimulateVolatility',
                                        transform='@TransformExpiryDate')

    daysToExpiry =              Object( label='Exp Days',
                                        objMapping='PricingOptions.DaysToExpiry',
                                        enabled=False)

    deliveryDate =              Object( label = 'Delivery',
                                        objMapping = 'PricingInstruments.DeliveryDate',
                                        onChanged='@UnsimulateVolatility',
                                        transform='@DeliveryDateFromPeriod',
                                        tabStop = False)

    daysToDelivery =            Object( label='Del Days',
                                        objMapping='PricingOptions.DaysToDelivery',
                                        enabled=False)

    payType =                   Object( label = 'Pay Type',
                                        objMapping = 'PricingInstruments.PayType',
                                        choiceListSource = ['Spot', 'Forward'],
                                        recreateCalcSpaceOnChange = True)

    settlementType =            Object( label = 'Settlement Type',
                                        objMapping = 'PricingOptions.SettlementType',
                                        choiceListSource = ['Physical', 'Cash'],
                                        visible='@ShowSettlementType')

    exerciseType =              Object( label='Exercise',
                                        objMapping='PricingInstruments.ExerciseType',
                                        transform='@TransformToOptionType',
                                        visible='@HasBaseTypeVanilla',
                                        choiceListSource='@ExerciseTypeChoiceList',
                                        recreateCalcSpaceOnChange = True)

    tradeTime =                 Object( defaultValue = acm.Time.DateToday(),
                                        label='Trade Time',
                                        objMapping='PricingTrades.TradeTime',
                                        transform='@TradeTimeFromPeriod')

    valueDay =                  Object( label='Value Day',
                                        objMapping='PricingTrades.ValueDay',
                                        transform='@ValueDayFromPeriod')

    tradeStatus =               Object( label = 'Status',
                                        objMapping = 'PricingTrades.Status',
                                        choiceListSource=TradeStatusChoices())

    portfolio =                 Object( label = 'Portfolio',
                                        objMapping = 'PricingTrades.Portfolio',
                                        choiceListSource=PortfolioChoices(),
                                        mandatory='@PortfolioIsMandatory')

    acquirer  =                 Object( label = 'Acquirer',
                                        objMapping = 'PricingTrades.Acquirer',
                                        choiceListSource=AcquirerChoices(),
                                        mandatory='@AcquirerIsMandatory')

    counterparty =              Object( label='Counterparty',
                                        objMapping='PricingTrades.Counterparty',
                                        choiceListSource=CounterpartyChoices(),
                                        mandatory='@TradeIsConfirmed',
                                        onChanged='@UpdateMirrorPortfolioChoices')

    counterpartyPortfolio =     Object( label='Cpty Portfolio',
                                        objMapping='CounterpartyPortfolio',
                                        visible='@MirrorPortfolioVisible',
                                        domain=acm.FPhysicalPortfolio,
                                        choiceListSource='@MirrorPortfolioChoices')

    trader =                    Object( label='Trader',
                                        objMapping='PricingTrades.Trader',
                                        mandatory='@TraderIsMandatory')

    broker =                    Object( label='Broker',
                                        objMapping='PricingTrades.Broker')

    memo =                      Object( defaultValue='',
                                        label='Memo',
                                        objMapping='DealPackage.AdditionalInfo.MemoString')

    instrumentPair =            Str(    label = 'Currency Pair',
                                        objMapping='InstrumentPair',
                                        transform='@TransformToInstrumentPair',
                                        onChanged='@OnInstrumentPairChanged|UpdateInstrumentChoices|UpdatePremiumCurrencyChoices')

    foreignInstrument =         Object( label='@ForeignCurrencyLabel',
                                        objMapping='PricingOptions.ForeignInstrument',
                                        transform='@TransformToForeignInstrument',
                                        choiceListSource='@ForeignCurrencyChoices',
                                        onChanged='@OnInstrumentPairChanged|UpdateInstrumentChoices|UpdatePremiumCurrencyChoices')

    domesticCurrency =          Object( label='@DomesticCurrencyLabel',
                                        objMapping='PricingOptions.DomesticCurrency',
                                        transform='@TransformToDomesticCurrency',
                                        choiceListSource='@DomesticCurrencyChoices',
                                        onChanged='@OnInstrumentPairChanged|UpdateInstrumentChoices|UpdatePremiumCurrencyChoices')

    strikeDomesticPerForeign =  Object( label='@StrikeDomPerForLabel',
                                        objMapping='PricingOptions.StrikeDomesticPerForeign',
                                        transform='@TransformStrikePrice',
                                        formatter='@StrikeFormatterCB',
                                        visible = '@IsNotDigitalAmerican',
                                        recreateCalcSpaceOnChange=True)

    strikeForeignPerDomestic =  Object( label='@StrikeForPerDomLabel',
                                        objMapping='PricingOptions.StrikeForeignPerDomestic',
                                        transform='@TransformStrikePrice',
                                        formatter='@StrikeFormatterInverseCB',
                                        visible = '@IsNotDigitalAmerican',
                                        recreateCalcSpaceOnChange=True)

    solverStrikeDomPerFor =     Object( label='@StrikeDomPerForLabel',
                                        objMapping='PricingOptions.StrikeDomesticPerForeignNoInputFormatter',
                                        transform='@TransformStrikePrice',
                                        solverParameter='@StrikeParamDomPerFor',
                                        onChanged='@SolverStrikeChanged')

    solverStrikeForPerDom =     Object( label='@StrikeForPerDomLabel',
                                        objMapping='PricingOptions.StrikeForeignPerDomesticNoInputFormatter',
                                        solverParameter='@StrikeParamForPerDom',
                                        onChanged='@SolverStrikeChanged')

    amountForeign =             Object( defaultValue=1000000,
                                        label='@ForeignAmountLabel',
                                        objMapping='PricingOptions.AmountForeign',
                                        transform='@AmountTransform',
                                        onChanged='@UpdateDealPackageTrade',
                                        formatter='@ForeignAmountFormatterCB',
                                        enabled='@ForeignAmountEnabled',
                                        recreateCalcSpaceOnChange=True)

    amountDomestic =            Object( label='@DomesticAmountLabel',
                                        objMapping='PricingOptions.AmountDomestic',
                                        transform='@AmountTransform',
                                        onChanged='@UpdateDealPackageTrade',
                                        formatter='@DomesticAmountFormatterCB',
                                        enabled='@DomesticAmountEnabled',
                                        recreateCalcSpaceOnChange=True)

    premiumCurrency =           Object( label='Premium Curr',
                                        objMapping='PricingOptions.PremiumCurrency',
                                        domain=acm.FCurrency,
                                        choiceListSource='@PremiumCurrencyChoices',
                                        onChanged='@UpdateDealPackageTrade|SetRoundingSpecification',
                                        transform='@TransformToValidCurrency')

    fixingSource =              Object( label='Fixing Source',
                                        objMapping='PricingInstruments.FixingSource',
                                        choiceListSource='@FixingSourceChoices',
                                        transform='@TransformToValidFixingSource')

    valGroup =                  Object( label='Val Group',
                                        objMapping='PricingInstruments.ValuationGrpChlItem',
                                        choiceListSource='@ValGroupChoices',
                                        recreateCalcSpaceOnChange=True,
                                        transform='@TransformToValidValGroup')

    saveIsFlippedSide =         Object( objMapping='PricingOptions.CurrentSaveIsFlipped',
                                        onChanged='@FlippedSideChanged')

    isQuoteCallOption =         Bool(   objMapping='IsQuoteCallOption')

    setForeignAsSave =          Action( label='@ForeignAmountLabel',
                                        action='@SetForeignAsSaveSide',
                                        recreateCalcSpaceOnChange=True,
                                        enabled='@IsNotDigital')

    setDomesticAsSave =         Action( label='@DomesticAmountLabel',
                                        action='@SetDomesticAsSaveSide',
                                        recreateCalcSpaceOnChange=True)

    buySell =                   Action( label='@BuySellHeader',
                                        action='@UpdateBuySell')

    removeSimulations =         Action( action='@RemoveSimulations')

    setSolverParameterAction =  Action( label='Set solverParameter',
                                        action='@SetSolverParameter')

    updateTradePriceFromTheor = Action( label='Update Trd Price',
                                        action='@UpdateTradePriceFromTheor')

    flipBidAskMode =            Action( label='Flip bid/ask mode',
                                        action='@FlipBidAskMode')

    flipPremiumCurrency =       Action( label='Flip Premium Currency',
                                        action='@FlipPremiumCurrency')

    refreshMarketDataPerAttr =  Action( label='Refresh Market Data Per Attribute',
                                        action='@RefreshMarketDataAttr')

    getStoredPricingParameters= Action(action='@GetStoredPricingParameters',
                                        noDealPackageRefreshOnChange=True)

    marketValuesLocked =        Bool(   objMapping = 'MarketValuesLocked')

    saveTradeQuotation =        Str(    label='Quotation',
                                        objMapping='SaveTradeQuotation',
                                        enabled=False)

    valuationModel =            Str(    label='Model',
                                        objMapping='ValuationModel')

    valuationAddOnModel =       Str(    label='Add On',
                                        objMapping='ValuationAddOnModel',
                                        visible='@ValuationAddOnModelUsed')

    bidAskMode =                Bool(   objMapping='BidAskMode')

    bidAskModeVol =             Bool(   objMapping='BidAskModeVol')

    volatility =                CalcVal(label = 'Vol %',
                                        calcMapping='VolatilityObjectsAsLot:FDealSheet:Portfolio Volatility FXOStrat',
                                        onChanged='@ValueSimulated|ReaplySimulation',
                                        transform='@TransformVolatility',
                                        solverParameter='@VolatilityParam')

    atmVolatility =             CalcVal(label = 'ATM Vol %',
                                        calcMapping='QuoteTrade:FDealSheet:ATM Volatility',
                                        onChanged='@ValueSimulated',
                                        _isUserSimulated='@IsCalculationUserSimulated',
                                        transform='@TransformVolatility',
                                        solverParameter='@VolatilityParam',
                                        enabled='@AtmVolatilityEnabled')

    undVal =                    CalcVal( calcMapping='CurrentSaveTrade:FDealSheet:Portfolio Underlying Price FXOStrat',
                                         formatter='@FXRateFlipFormatterCB',
                                         transform='@TransformPriceParse',
                                         onChanged='@ValueSimulated',
                                         calcConfiguration='@UsePerUnitQuotation',
                                         _isUserSimulated='@IsCalculationUserSimulated',
                                         solverParameter='@UndValParam')

    customCalculations =        List(   label='@CustomCalcLabel',
                                        action='@GetCustomCalculation',
                                        visible=True,
                                        enabled=False,
                                        noDealPackageRefreshOnChange=True)

    saveTradeCalcVal =          SaveTradeCalculations()

    customerAttributes =        CustomerAdditionalAttributes(tradeNames = 'PricingTrades')

    # -------------------------------------------------------------------------------
    # Action to use when flipping a strip of options to flip simulations
    # -------------------------------------------------------------------------------
    flipSaveTradeSimulations =  Action( action = '@FlipSaveTradeCalcSimulations' )

    '''*******************************************************
    * Trade/Instrument Get methods
    *******************************************************'''
    def PricingOptions(self):
        return self._pricingOptions

    def PricingTrades(self):
        return self.PricingOptions().Trades()

    def PricingInstruments(self):
        return self.PricingOptions().Instruments()

    def CurrentSaveTrade(self):
        return self.PricingOptions().CurrentSaveTrades().First()

    def FXRatesToLock(self):
        if self.foreignInstrument.IsKindOf('FCommodityVariant'):
            cmdCurr = self.foreignInstrument.Underlying().Currency()
            tradeCurr = self.domesticCurrency
            if cmdCurr != tradeCurr:
                fxRate = acm.GetFunction('CreateFxRate', 2)
                return acm.FLot([fxRate(cmdCurr, tradeCurr), fxRate(tradeCurr, cmdCurr)])

    def AsPortfolio(self):
        return self.DealPackage().AsPortfolio()

    '''*******************************************************
    * Helper Methods
    *******************************************************'''
    def GetUnderlyingValue(self, name):
        value = None
        if name in ['strikeDomesticPerForeign', 'solverStrikeDomPerFor', 'strike2DomesticPerForeign', 'solverStrike2DomPerFor']:
            value = self.quoteTradeCalcVal_undVal
        elif name in ['strikeForeignPerDomestic', 'solverStrikeForPerDom', 'strike2ForeignPerDomestic', 'solverStrike2ForPerDom']:
            value = self.flippedQuoteTradeCalcVal_undVal
        #Used to keep old logic, should be removed
        buySell = ('Buy' if self.BuySellLabel() == 'Sell' else 'Sell') if self.IsPutOptionForSide(name) else self.BuySellLabel()
        return GetFloatFromCalculation(value, buySell)

    def GetForwardValue(self, name):
        value = None
        if name in ['strikeDomesticPerForeign', 'solverStrikeDomPerFor', 'strike2DomesticPerForeign', 'solverStrike2DomPerFor']:
            value = self.quoteTradeCalcVal_fwd
        elif name in ['strikeForeignPerDomestic', 'solverStrikeForPerDom', 'strike2ForeignPerDomestic', 'solverStrike2ForPerDom']:
            value = self.flippedQuoteTradeCalcVal_fwd
        #Used to keep old logic, should be removed
        buySell = ('Buy' if self.BuySellLabel() == 'Sell' else 'Sell') if self.IsPutOptionForSide(name) else self.BuySellLabel()
        return GetFloatFromCalculation(value, buySell)

    def SetNewSaveTradeOnDealPackage(self):
        # Overridden in sub class
        pass

    def GetDeltaHedgeValueFromAttribute(self, attributeName):
        retVal = self.GetAttribute(attributeName).Value()
        if IsOfTypeFLot(retVal):
            if self.CurrentSaveTrade().Quantity() > 0:
                retVal = retVal[0].Number()
            else:
                retVal = retVal[1].Number()
        else:
            retVal = retVal.Number()
        return retVal

    def IsFxOption(self):
        return IsFxOption(self.QuoteInstrument())

    def IsPmOption(self):
        return not IsFxOption(self.QuoteInstrument())

    def ParentIsStrip(self):
        isStrip = False
        if self.DealPackage().ParentDealPackage():
            isStrip = str(self.DealPackage().ParentDealPackage().DefinitionName()) == 'FXStripDealPackage'
        return isStrip

    def SetAttributeOnStrip(self, attrName, val):
        if self.ParentIsStrip():
            self.DealPackage().ParentDealPackage().SetAttribute(attrName, val)
            self.DealPackage().ParentDealPackage().Refresh()
        else:
            raise DealPackageException("Parent is not a Strip")

    def StoreMarketValues(self, attributeToStore = None):
        try:
            attributesToStore = [attributeToStore] if attributeToStore else self._storedPricingParameters.keys()
            calcCopy = self.GetCalculationsCopy(copySimulations = False)
            for attribute in list(attributesToStore):
                if not self.GetCalculation(attribute):
                    if self.FXRatesToLock():
                        self.CreateCalculation(attribute, 'FXRatesToLock:FDealSheet:%s' % attribute)
                        calcCopy.CreateMissingCalculations(acm.GetFunction('createDictionary', 2)(attribute, self._dealPackageCalculations.Calculation(attribute)))
                    else:
                        attributesToStore.remove(attribute)
                        continue
                self._storedPricingParameters[attribute] = [self.GetValueToStore(attribute, calcCopy.Value(attribute).Value()), None]
            calcCopy.SimulateValue('useBidOrAskPrice', ['Bid', 'Ask'])
            calcCopy.SimulateValue('alternativeContext', ["Bid", "Ask"])
            for attribute in attributesToStore:
                self._storedPricingParameters[attribute][1] = self.GetValueToStore(attribute, calcCopy.Value(attribute).Value())
            calcCopy.TearDown()
        except Exception as e:
            self.Log().Error('Failed to store market values. %s' % e)
            if not attributeToStore:
                for attribute in self._storedPricingParameters:
                    self._storedPricingParameters[attribute] = None
                    if not hasattr(self, attribute):
                        self.RemoveCalculation(attribute)

    def LockMarketValues(self, lockSimulatedValues = False):
        if self.MarketValuesLocked():
            for attribute, storedValue in sorted(self._storedPricingParameters.items()):
                #Using sorted because fxSpotRate has to be locked before quoteTradeCalcVal_undVal.
                #UndVal is using fxSpotRate in column transform
                if not storedValue:
                    continue
                bidAskMode = self.BidAskModeVol() if attribute.lower().find('volatility') != -1 else self.BidAskMode()
                if lockSimulatedValues or not self.IsCalculationUserSimulated(attribute):
                    value = storedValue[1] if bidAskMode else storedValue[0]
                    if hasattr(self, attribute):
                        setattr(self, attribute, value)
                    else:
                        self.SimulateCalculation(attribute, value)

    def RefreshLockedValue(self, attribute):
        if self._storedPricingParameters.get(attribute):
            self.StoreMarketValues(attribute)
        self.UnsimulateAttributeValue(attribute)

    def GetCalculationsCopy(self, copyCalculations = True, copySimulations = True, setBidAsk = None):
        calcCopy = DealPackageCalculations(self, 1)
        for traitName in self._GetTraitNames():
            calcInfo = self.trait_metadata(traitName, "calcMapping")
            if calcInfo and self._GetTrait(traitName).__class__ == CalcVal:
                configurationCb = self._GetAttributeMetaDataCallback(traitName, "calcConfiguration")
                calcObjCb, columnId, columnIdCb, sheetType = self._GetCalcSpecFromTraitInfo(calcInfo)
                calcCopy.CreateCalculation(traitName, calcObjCb, sheetType, columnId, columnIdCb, configurationCb)
        if copyCalculations:
            calcCopy.CreateMissingCalculations(self._GetCalculations())
        if copySimulations:
            calcCopy.ApplySimulations(self._GetSimulations())
        if setBidAsk == True:
            calcCopy.SimulateValue('useBidOrAskPrice', ['Bid', 'Ask'])
            calcCopy.SimulateValue('alternativeContext', ["Bid", "Ask"])
        elif setBidAsk == False:
            calcCopy.SimulateValue('useBidOrAskPrice', '')
            calcCopy.SimulateValue('alternativeContext', '')
            simulations = calcCopy.Simulations()
            for attribute in simulations:
                simulatedValue = simulations[attribute]
                if IsBidAskValue(simulatedValue):
                    #Simulated value is bid ask but not in bid ask mode, use mid
                    calcCopy.SimulateValue(attribute, sum(map(ParseFloat, simulatedValue)) / len(simulatedValue))
        return calcCopy

    def GetValueToStore(self, attribute, value = None):
        calc = self.GetCalculation(attribute)
        if IsIterable(calc) and hasattr(self, attribute):
            calc = calc[0]
        if value is None:
            try:
                value = calc.Value()
            except Exception as e:
                self.Log().Error('Failed to get value for %s. [%s]' % (attribute, e))
                return
        if value and hasattr(self, attribute):
            value /= calc.Parse(1.0) #Assume calculation formatting is only inverse scaling of parse
            if IsBidAskValue(value):
                if value[0] == value[-1]:
                    value = value[0]
                else:
                    value = [v for v in value]
        return value

    def GetColumnFormatter(self, attributeName):
        return self._DealPackageBase__ColumnFormatter(attributeName)

    '''*******************************************************
    * Action methods
    *******************************************************'''
    def UpdateBuySell(self, *args):
        if self.PricingOptions().CurrentSaveIsFlipped():
            self.amountDomestic = -self.amountDomestic
        else:
            self.amountForeign = -self.amountForeign

    def SetCurrentSaveToQuote(self):
        self.PricingOptions().SetCurrentSaveToQuote()
        self.SetNewSaveTradeOnDealPackage()

    def SetCurrentSaveToFlipped(self):
        self.PricingOptions().SetCurrentSaveToFlipped()
        self.SetNewSaveTradeOnDealPackage()

    def SetForeignAsSaveSide(self, *args):
        if self.IsDigital():
            self.payoutCurrency = self.foreignInstrument
        self.SetCurrentSaveToQuote()

    def SetDomesticAsSaveSide(self, *args):
        if self.IsDigital():
            self.payoutCurrency = self.domesticCurrency
        else:
            self.SetCurrentSaveToFlipped()

    def RemoveSimulations(self, *args):
        bidAskMode = self.bidAskMode
        self.RemoveAllSimulations()
        self.BidAskMode(bidAskMode)
        self.LockMarketValues(True)

    def TransformStrikeSolverAttr(self, guiAttr):
        return GuiAttributeToSolverAttributeName(guiAttr)

    def ValidateSolverParameter(self, newSolverParameter):
        return self.GetAttributeMetaData(newSolverParameter, 'solverParameter')()

    def SetSolverParameter(self, attrName, newSolverParameter):
        newSolverParameter = self.TransformStrikeSolverAttr(newSolverParameter)
        if self.ValidateSolverParameter(newSolverParameter):
            self.solverParameter = newSolverParameter

    def GetTheorPrcForCurrentSaveTrade(self):
        theorPrc = None
        if self.PricingOptions().CurrentSaveIsQuoteTrade():
            theorPrc = self.quoteTradeCalcVal_theor
        elif self.PricingOptions().CurrentSaveIsAltQuoteTrade():
            theorPrc = self.quoteTradeCalcVal_theorPct
        elif self.PricingOptions().CurrentSaveIsFlippedQuoteTrade():
            theorPrc = self.flippedQuoteTradeCalcVal_theor
        elif self.PricingOptions().CurrentSaveIsFlippedAltQuoteTrade():
            theorPrc = self.flippedQuoteTradeCalcVal_theorPct
        return theorPrc

    def UpdateTradePriceFromTheor(self, *args):
        try:
            self.tradePrice = GetFloatFromCalculation(self.GetTheorPrcForCurrentSaveTrade(), self.BuySellLabel())
        except Exception as e:
            # Can't trust the theor to always be OK
            pass

    def FlipBidAskMode(self, *args):
        self.bidAskMode = not self.bidAskMode

    def RefreshMarketDataAttr(self, attrName, updateValueForAttrName):
        if self._storedPricingParameters.get(updateValueForAttrName):
            self.RefreshLockedValue(updateValueForAttrName)
        else:
            setattr(self, updateValueForAttrName, None)

    def UsePerUnitQuotation(self, attrName):
        return UsePerUnitQuotationImpl(attrName)

    def IsCalculationUserSimulatedImpl(self, attributeName):
        if self.IsCalculationSimulated(attributeName):
            storedValue = self._storedPricingParameters.get(attributeName)
            if storedValue:
                #storedValue = storedValue[-1] if self.bidAskMode else storedValue[0]
                attributeValue = self.GetValueToStore(attributeName)
                if ValuesAreEqual(storedValue[0], attributeValue) or ValuesAreEqual(storedValue[-1], attributeValue):
                    #Comparing with both to get correct behavior when changing bid/ask mode
                    return False
            return True
        return False

    def GetOppositeSimulationAttribute(self, attributeName):
        try:
            if self.GetAttributeMetaData(attributeName, '_setOppositeSideAsSimulated')():
                oppositeAttributeName = GetOppositeAttributeName(attributeName)
                if oppositeAttributeName in self.DealPackage().GetAttributes():
                    return oppositeAttributeName
        except:
            #Will fail if you call the method with a caluclation which isn't an attribute
            pass

    def IsCalculationUserSimulated(self, attributeName):
        if not self.IsCalculationUserSimulatedImpl(attributeName):
            oppositeAttributeName = self.GetOppositeSimulationAttribute(attributeName)
            if oppositeAttributeName:
                return self.IsCalculationUserSimulatedImpl(oppositeAttributeName)
            return False
        return True

    def ChangeCallPut(self, *args):
        self.PricingOptions().ChangeCallPut()

    def DeltaHedgeIsEnabled(self):
        pass

    def TradeIsConfirmed(self, *args):
        return not self.tradeStatus in ('Simulated', 'Reserved', 'Void')

    def AcquirerIsMandatory(self, *args):
        return self.TradeIsConfirmed() or self.DeltaHedgeIsEnabled()

    def TraderIsMandatory(self, *args):
        installData  = acm.FInstallationData.Instances().First()
        return self.TradeIsConfirmed() and installData.TraderMandatory()

    def PortfolioIsMandatory(self, *args):
        installData  = acm.FInstallationData.Instances().First()
        portfolioMandatory = installData.PhysicalPortfolioMandatory()
        return (self.TradeIsConfirmed() and portfolioMandatory) or self.DeltaHedgeIsEnabled()

    def FlipSaveTradeCalcSimulations(self, attrName, isFlipped, *args):
        # Override in sub classes
        pass

    def FlipPremiumCurrency(self, *args):
        if self.foreignInstrument == self.premiumCurrency:
            self.premiumCurrency = self.domesticCurrency
        else:
            self.premiumCurrency = self.foreignInstrument

    '''*******************************************************
    * Object Mapping methods
    *******************************************************'''
    def ValuationModel(self, notUsed = None):
        if notUsed:
            pass
        return self.CurrentSaveTrade().Instrument().ValuationModel()

    def ValuationAddOnModel(self, notUsed = None):
        if notUsed:
            pass
        return self.CurrentSaveTrade().Instrument().ValuationAddOnModel()

    def IsQuoteCallOption(self, notUsed = None):
        if notUsed:
            pass
        return self.QuoteTrade().Instrument().IsCall()

    def InstrumentPair(self, instrPair = None):
        if not instrPair:
            return self.PricingOptions().InstrumentPair().Name()
        else:
            self.PricingOptions().InstrumentPair(instrPair)

    def SaveTradeQuotation(self, notUsed = None):
        if notUsed:
            pass
        return QuotationLabel(self.CurrentSaveTrade())

    def VolatilityObjectsAsLot(self, notUsed = None):
        #Not implemented in base class
        raise NotImplementedError()

    def BidAskMode(self, setBidAskMode = None):
        if not self._dealPackageCalculations:
            return False
        if not self.GetCalculation('useBidOrAskPrice'):
            self.CreateCalculation('useBidOrAskPrice', 'Trade:FDealSheet:useBidOrAskPrice')
        bidAskMode = IsBidAskValue(self.GetCalculation('useBidOrAskPrice').Value())
        if setBidAskMode == None:
            return bidAskMode
        elif setBidAskMode == bidAskMode:
            self.BidAskModeVol(setBidAskMode)
            return
        self.SimulateCalculation('useBidOrAskPrice', ['Bid', 'Ask'] if setBidAskMode else "")
        if self.BidAskModeVol(setBidAskMode) is None:
            self.LockMarketValues()
        if not setBidAskMode:
            for attribute in self._GetSimulations():
                simulatedValue = self._GetSimulations()[attribute]
                if IsBidAskValue(simulatedValue) and hasattr(self, attribute):
                    #Simulated value is bid ask but not in bid ask mode, use mid
                    setattr(self, attribute, sum(map(ParseFloat, simulatedValue)) / len(simulatedValue))

    def BidAskModeVol(self, setBidAskMode = None):
        if not self._dealPackageCalculations:
            return False
        if not self.GetCalculation('alternativeContext'):
            self.CreateCalculation('alternativeContext', 'Trade:FDealSheet:alternativeContext')
        bidAskMode = IsBidAskValue(self.GetCalculation('alternativeContext').Value())
        if setBidAskMode == None:
            return bidAskMode
        elif bidAskMode != setBidAskMode:
            if setBidAskMode and not IsValidBidAskVolatilitySurfaces(self.PricingInstruments().First().Instrument()):
                return bidAskMode
            self.SimulateCalculation('alternativeContext', ['Bid', 'Ask'] if setBidAskMode else "")
            self.LockMarketValues()
            return setBidAskMode

    def MarketValuesLocked(self, lockOrUnlockValues = None):
        if lockOrUnlockValues == None:
            for value in self._storedPricingParameters.values():
                if value != None:
                    return True
            return False
        elif lockOrUnlockValues == True:
            self.StoreMarketValues()
            self.LockMarketValues()
        elif lockOrUnlockValues == False:
            for attribute in self._storedPricingParameters:
                if not hasattr(self, attribute):
                    self.RemoveCalculation(attribute)
                elif not self.IsCalculationUserSimulated(attribute):
                    self.SimulateCalculation(attribute, "") #Remove simulation
                self._storedPricingParameters[attribute] = None

    '''*******************************************************
    * OnChanged methods
    *******************************************************'''
    def ValueSimulated(self, attributeName, old, new, userInputAttributeName):
        if self.IsCalculationSimulated(attributeName):
            if TurnOffRealTimeUpdatesOnSimulation() and not self.MarketValuesLocked():
                if self.ParentIsStrip():
                    self.SetAttributeOnStrip('marketValuesLocked', True)
                else:
                    self.marketValuesLocked = True
                self.ReaplySimulation(attributeName, old, new, userInputAttributeName)
        else:
            self.UnsimulateAttributeValue(attributeName)

    def ReaplySimulation(self, attributeName, old, new, userInputAttributeName):
        simulatedValue = self.GetSimulatedCalculationValue(attributeName)
        self.SimulateCalculation(attributeName, '')
        self.SimulateCalculation(attributeName, simulatedValue)

    def UnsimulateVolatility(self, attributeName, old, new, userInputAttributeName):
        self.UnsimulateAttributeValue('volatility')
        #self.RefreshLockedValue('atmVolatility')

    def SetRoundingSpecification(self, attributeName, old, new, userInputAttributeName):
        roundingSpec = self.premiumCurrency.RoundingSpecification()
        for instrument in self.PricingInstruments():
            for ins in instrument.Instruments() if instrument.IsKindOf('FCombination') else [instrument]:
                ins.RoundingSpecification(roundingSpec)

    def SetDefaultStrike(self):
        self.DealPackage().SetAttribute('solverStrikeDomPerFor', 'atmf')

    def Refresh(self):
        try:
            if self._updateDefaultStrike:
                self.SetDefaultStrike()
                self.tradePrice = 0
        except Exception as e:
            print (e)
        finally:
            self._updateDefaultStrike = False

    def OnInstrumentPairChanged(self, attr, oldVal, newVal, userInputTraitName):
        if userInputTraitName == None:
            self.MarketValuesLocked(False)
            self.GetAttribute('removeSimulations')()
            self.solverParameter = 'solverStrikeDomPerFor'
            self._updateDefaultStrike = True

    def UpdatePremiumCurrencyChoices(self, *args):
        self._premiumCurrencyChoices.Clear()
        if self.IsFxOption():
            self._premiumCurrencyChoices.AddAll([self.foreignInstrument, self.domesticCurrency])
        else:
            self._premiumCurrencyChoices.AddAll([self.domesticCurrency])

    def UpdateDealPackageTrade(self, attr, oldVal, newVal, userInputtedAttr):
        if oldVal and newVal and not userInputtedAttr:
            self.SetNewSaveTradeOnDealPackage()

    def FlippedSideChanged(self, *args):
        # Overridden in sub class
        pass

    '''*******************************************************
    * Choices methods
    *******************************************************'''
    def PremiumCurrencyChoices(self, *args):
        if self._premiumCurrencyChoices.IsEmpty():
            self.UpdatePremiumCurrencyChoices()
        return self._premiumCurrencyChoices

    def ExerciseTypeChoiceList(self, *args):
        return ['European', 'American']

    def FixingSourceChoices(self, *args):
        return GetFixingSourceChoices()

    def ValGroupChoices(self, *args):
        return GetValGroupChoices()

    def UpdateInstrumentChoices(self, *args):
        self._foreignInstrumentChoices.Clear()
        self._domesticCurrencyChoices.Clear()
        if self.IsFxOption():
            self._foreignInstrumentChoices.AddAll(list(self.QuoteInstrument().DefaultForeignCurrencies()))
            self._domesticCurrencyChoices.AddAll(list(self.QuoteInstrument().DefaultDomesticCurrencies()))
        else:
            self._foreignInstrumentChoices.AddAll(list(PreciousMetalChoiceList(self.QuoteInstrument())))
            self._domesticCurrencyChoices.AddAll(list(self.QuoteInstrument().DefaultPreciousMetalCurrencies()))

    def ForeignCurrencyChoices(self, *args):
        if self._foreignInstrumentChoices.IsEmpty():
            self.UpdateInstrumentChoices()
        return self._foreignInstrumentChoices

    def DomesticCurrencyChoices(self, *args):
        if self._domesticCurrencyChoices.IsEmpty():
            self.UpdateInstrumentChoices()
        return self._domesticCurrencyChoices

    '''*******************************************************
    * Visible methods
    *******************************************************'''
    def ValuationAddOnModelUsed(self, *args):
        return ValuationAddOnModelIsUsed(self.CurrentSaveTrade().Instrument())

    def IsDigital(self):
        # Overridden in sub class
        return False

    def IsDigitalAmerican(self):
        # Overridden in sub class
        return False

    def ShowSettlementType(self, *args):
        if self.IsFxOption():
            return self.IsNotDigital(args)
        else:
            return True

    def IsNotDigital(self, *args):
        return not self.IsDigital()

    def IsNotDigitalAmerican(self, *args):
        return not self.IsDigitalAmerican()

    def HasBaseTypeVanilla(self, *args):
        # Overridden in sub class
        if not hasattr(self, 'baseType'):
            return True
        return self.baseType == 'Vanilla'

    '''*******************************************************
    * Transform methods
    *******************************************************'''
    def TransformDelta(self, name, newDelta):
        delta = self.ChangeSignOnDeltaBasedOnCallPut(ParseFloat(newDelta), False)
        return str(delta)

    def TransformFlippedDelta(self, name, newDelta):
        delta = self.ChangeSignOnDeltaBasedOnCallPut(ParseFloat(newDelta), True)
        return str(delta)

    def SolveStrikeForPremiumAdjustedDelta(self, solverParameter, attributeName, delta):
        precision = 0.0001
        maxIterations = 100

        # Possible attributeName values:
        #       1) quoteTradeCalcVal_deltaBSAlt
        #       2) flippedQuoteTradeCalcVal_deltaBSAlt
        #       3) deltaBSAltCall
        #       4) deltaBSFlippedAltCall

        isSolverValueQuote = False if 'flipped' in attributeName.lower() else True
        isSolverParameterQuote = solverParameter.endswith('For')

        #if isSolverParameterQuote:
        #    fwdPrice = GetFloatFromCalculation(self.quoteTradeCalcVal_fwd, self.BuySellLabel()) if self.quoteTradeCalcVal_fwd else 1.0
        #else:
        #    fwdPrice = GetFloatFromCalculation(self.flippedQuoteTradeCalcVal_fwd, self.BuySellLabel()) if self.flippedQuoteTradeCalcVal_fwd else 1.0

        fwdPrice = GetFloatFromCalculation(self.quoteTradeCalcVal_fwd, self.BuySellLabel()) if self.quoteTradeCalcVal_fwd else 1.0

        maxStrike = self.DealPackage().Solve(solverParameter, attributeName.replace('Alt', ''), delta, fwdPrice/3, fwdPrice*3, precision, maxIterations)
        minStrike = maxStrike * 0.9

        # Increase maxStrike boundary by 10% when solving
        # strike for flipped premium adjusted delta.
        if isSolverValueQuote != isSolverParameterQuote:
            maxStrike = maxStrike * 1.1

        with SetSolverParametersWithSafeExit(self, attributeName, solverParameter, delta):
            strike = self.DealPackage().Solve(solverParameter, attributeName, delta, minStrike, maxStrike, precision, maxIterations)

        isFinite = acm.Math.IsFinite(strike)
        if isFinite:
            return strike
        else:
            raise DealPackageException("No solution found for '%s' that gives expected '%s' of %s. "
                                "(Using boundary conditions min = %f, max = %f, precision = %f, max iterations = %d)."
                                %(solverParameter, attributeName, delta, minStrike, maxStrike, precision, maxIterations))

    def TransformPremiumAdjustedDelta(self, attributeName, delta):
        # Since the premium adjusted call delta is not strictly
        # monotone vs strike, we need to obtain valid strike
        # boundaries. The right limit (maxStrike) is chosen as
        # the strike corresponding to the non-premium adjusted
        # delta, since the premium adjusted delta for strike
        # K is always smaller than the non-premium adjusted delta
        # corresponding to the same strike. The left limit (minStrike)
        # is chosen to be 10% smaller than maxStrike.

        validSolverParameters = ['solverStrikeDomPerFor', 'solverStrikeForPerDom', 'solverStrike2DomPerFor', 'solverStrike2ForPerDom']

        if self.solverParameter in validSolverParameters:
            if attributeName.startswith('flipped'):
                delta = self.TransformFlippedDelta(attributeName, delta)
            else:
                delta = self.TransformDelta(attributeName, delta)

            form = self.GetColumnFormatter(attributeName)
            delta = ParseFloat(delta, formatter=form)

            isCallOption = self.IsCallOptionForSide(attributeName)
            if isCallOption:
                strike = self.SolveStrikeForPremiumAdjustedDelta(self.solverParameter, attributeName, delta)
                setattr(self, self.solverParameter, strike)
                delta = self.GetValueToStore(attributeName)

        return delta

    def DeliveryDateFromPeriod(self, name, newDate):
        date = newDate
        if acm.Time().PeriodSymbolToDate(newDate):
            decoNoGUI = acm.FBusinessLogicDecorator.WrapObject(self.Instrument().Instrument())
            date = decoNoGUI.DeliveryDateFromPeriod(newDate)
        return date

    def TransformExpiryDate(self, name, newDate):
        return TransformExpiryInputStrToDate(newDate, name)

    def TradeTimeFromPeriod(self, name, newDate):
        if acm.Time().PeriodSymbolToDate(newDate):
            newDate= acm.Time().PeriodSymbolToDate(newDate)
        return newDate

    def ValueDayFromPeriod(self, name, newDate):
        if acm.Time().PeriodSymbolToDate(newDate):
            startDate = self.CurrentSaveTrade().Instrument().SpotDate(self.tradeTime)
            newDate = acm.Time().PeriodSymbolToRebasedDate(newDate, startDate)
        return newDate

    def TransformToOptionType(self, name, value):
        return TransformToOptionTypeFromStr(value)

    def TransformToInstrumentPair(self, name, value):
        instrPairName = InstrumentPairFromStr(value, self.instrumentPair, self.IsFxOption())
        userEnteredInverseQuote = CallPutFromInstrumentPairFromStr(self.instrumentPair, instrPairName, value)
        if userEnteredInverseQuote is not None:
            if not self.IsQuoteCallOption() == userEnteredInverseQuote: # Put + inverse -> call, call + not inverse -> put
                self.ChangeCallPut()
        return instrPairName

    def FindInstrumentOrPairFromString(self, inputStr, isForeign, isFxOption):
        value = inputStr
        if inputStr:
            value = InstrumentFromStr(inputStr, isFxOption if isForeign else True)
            if not value:
                value = self.TransformToInstrumentPair(None, inputStr)
        return value

    def FindCurrOrPairFromStr(self, currentInstr, otherInstr, inputStr, isForeign, isFxOption):
        currOrPairStr = None
        try:
            instrOrPairFromInputStr = self.FindInstrumentOrPairFromString(inputStr, isForeign, isFxOption)
            if instrOrPairFromInputStr and acm.FInstrument[instrOrPairFromInputStr]:
                otherInstrStr = otherInstr.Name() if otherInstr else None
                instrPair = GetInstrumentPairFromInput(str(instrOrPairFromInputStr+'/'+otherInstrStr), isFxOption)
                compareWithCurr = instrPair.Instrument1().Name() if isForeign else instrPair.Instrument2().Name()
                currOrPairStr = instrOrPairFromInputStr if compareWithCurr == instrOrPairFromInputStr else instrPair.Name()
            else:
                currOrPairStr = instrOrPairFromInputStr
        except Exception as e:
            currOrPairStr = self.TransformToInstrumentPair(None, inputStr)

        if not currOrPairStr:
            currOrPairStr = currentInstr.Name() if currentInstr else None
        return currOrPairStr

    def TransformToForeignInstrument(self, name, inputStr):
        return self.FindCurrOrPairFromStr(self.foreignInstrument, self.domesticCurrency, inputStr, True, self.IsFxOption())

    def TransformToDomesticCurrency(self, name, inputStr):
        return self.FindCurrOrPairFromStr(self.domesticCurrency, self.foreignInstrument, inputStr, False, self.IsFxOption())

    def ChangeSignOnDeltaBasedOnCallPut(self, delta, isFlippedDelta = False):
        return delta

    def GetSolvedStrikeFromDelta(self, name, value):
        value = value[:-1]
        if name in ['strikeDomesticPerForeign', 'solverStrikeDomPerFor', 'strike2DomesticPerForeign', 'solverStrike2DomPerFor']:
            topValue = 'quoteTradeCalcVal_deltaBSAlt' if self.PricingOptions().CurrentSaveIsAltQuoteTrade() else 'quoteTradeCalcVal_deltaBS'
        elif name in ['strikeForeignPerDomestic', 'solverStrikeForPerDom', 'strike2ForeignPerDomestic', 'solverStrike2ForPerDom']:
            topValue = 'flippedQuoteTradeCalcVal_deltaBSAlt' if self.PricingOptions().CurrentSaveIsFlippedAltQuoteTrade() else 'flippedQuoteTradeCalcVal_deltaBS'
        else:
            return getattr(self, name)

        solverParameter = GuiAttributeToSolverAttributeName(name)
        delta = ParseFloat(value, formatter=getattr(self, topValue))
        delta = self.ChangeSignOnDeltaBasedOnCallPut(delta, topValue.startswith('flipped'))

        solvedStrike = None
        if topValue in ['quoteTradeCalcVal_deltaBSAlt', 'flippedQuoteTradeCalcVal_deltaBSAlt']:
            solvedStrike = self.SolveStrikeForPremiumAdjustedDelta(solverParameter, topValue, delta)
        else:
            solvedStrike = self.Solve(topValue, solverParameter, delta)

        return solvedStrike

    def GetIntrinsicAttribute(self, name, isFwd):
        return 'intrinsicFwd' if isFwd else 'intrinsicSpot'

    def GetSolvedStrikeFromIntrinsic(self, name, value):
        intrinsicAttribute = self.GetIntrinsicAttribute(name, value[-1] == 'f')
        intrinsic = ParseFloat(value, formatter=getattr(self, intrinsicAttribute))
        if getattr(self, intrinsicAttribute) == None:
            return
        return self.Solve(intrinsicAttribute, GuiAttributeToSolverAttributeName(name), intrinsic)

    def IsPutOptionForSide(self, attrName):
        if Flipped(attrName):
            return self.IsQuoteCallOption()
        else:
            return not self.IsQuoteCallOption()

    def IsCallOptionForSide(self, attrName):
        return not self.IsPutOptionForSide(attrName)

    def TransformStrikePrice(self, name, value):

        if isinstance(value, str):
            value = value.lower()

        if value in ['atm', '*', 'atms', 's']:
            value = self.GetUnderlyingValue(name)
        elif value in ['atmf', 'f']:
            value = self.GetForwardValue(name)
        elif isinstance(value, str) and value.endswith('d'):
            value = self.GetSolvedStrikeFromDelta(name, value)
        elif isinstance(value, str) and (value.endswith('p') or value.endswith('pf')):
            value = self.GetSolvedStrikeFromIntrinsic(name, value)
        if not value:
            # Fallback
            value = self.CurrentSaveTrade().Instrument().StrikePrice()

        return value

    def UnsimulateAttributeValueImpl(self, attrName):
        value = self._storedPricingParameters.get(attrName)
        if value != None:
            bidAskMode = self.BidAskModeVol() if attrName.lower().find('volatility') != -1 else self.BidAskMode()
            value = value[0] if not bidAskMode else value[1]
            value = self._GetTransform(attrName)(value)
        self.SimulateCalculation(attrName, value)

    def UnsimulateAttributeValue(self, attrName):
        oppositeAttrName = self.GetOppositeSimulationAttribute(attrName)
        if oppositeAttrName:
            if oppositeAttrName in self._storedPricingParameters:
                self.UnsimulateAttributeValueImpl(attrName)
                attrName = oppositeAttrName
            else:
                self.UnsimulateAttributeValueImpl(oppositeAttrName)
        self.UnsimulateAttributeValueImpl(attrName)

    def TransformBidAskSplit(self, attrName, value):
        if isinstance(value, str):
            valueSplit = value.split('/')
            if len(valueSplit) == 2:
                v0 = valueSplit[0].replace(' ', '')
                v1 = valueSplit[1].replace(' ', '')
                if not v0:
                    self.RefreshLockedValue(attrName)
                    if not v1:
                        #Use unsimulated bid/ask value
                        value = 'ValueWillNotBeSet'
                    else:
                        val = self.GetValueToStore(attrName)
                        if IsBidAskValue(val):
                            val = val[0]
                        value = [val.Number() if hasattr(val, 'Number') else val, v1]
                elif not v1:
                    self.RefreshLockedValue(attrName)
                    val = self.GetValueToStore(attrName)
                    if IsBidAskValue(val):
                        val = val[1]
                    value = [v0, val.Number() if hasattr(val, 'Number') else val]
                else:
                    value = TransformDecimalPoints([v0, v1])
        return value

    def TransformBidAsk(self, attrName, value):
        if isinstance(value, str) and len(value.split('/')) == 2:
            self.bidAskMode = True
        if value in [None, ''] and not self.IsCalculationSimulated(attrName):
            oppositeAttrName = self.GetOppositeSimulationAttribute(attrName)
            if oppositeAttrName and self.IsCalculationSimulated(oppositeAttrName):
                self.UnsimulateAttributeValue(oppositeAttrName)
        return self.TransformBidAskSplit(attrName, value)

    def TransformPrice(self, attrName, value):
        value = self.TransformBidAsk(attrName, value)
        if not self._isSolverDealPackage and value != 'ValueWillNotBeSet':
            currentValue = GetFloatFromCalculation(getattr(self, attrName))
            value = TransformMagnitude(value, currentValue)
        return value

    def TransformPriceParse(self, attrName, value):
        value = self.TransformPrice(attrName, value)
        formatter = self.GetAttributeMetaData(attrName, 'formatter')()
        if formatter and hasattr(formatter, 'Parse'):
            value = formatter.Parse(value)
        return value

    def TransformVolatility(self, attrName, value):
        if value in ('', None):
            self.bidAskModeVol = self.bidAskMode
        elif isinstance(value, str) and len(value.split('/')) == 2:
            self.bidAskModeVol = True
        else:
            self.bidAskModeVol = False
        return self.TransformBidAskSplit(attrName, value)

    def AmountTransform(self, attrName, value):
        if not isinstance(value, basestring):
            return value

        if value.startswith( ('+', '-') ):
            sign = {'+':1, '-':-1}[value[0]]
        else:
            sign = -1 if getattr(self, attrName) < 0 else 1

        formatter = self.GetAttributeMetaData(attrName, 'formatter')()
        parsedValue = formatter.Parse(value)

        return sign * abs(parsedValue) if parsedValue else value

    def TransformToValidCurrency(self, attrName, value, *rest):
        if type(value) == types.StringType:
            curr = InstrumentFromStr(value, True)
            if curr != None:
                return curr
            else:
                return getattr(self, attrName)
        return value

    def TransformToValidFixingSource(self, attrName, value, *rest):
        if type(value) == types.StringType:
            source = FixingSourceFromString(value)
            if source != None:
                return source
            else:
                return getattr(self, attrName)
        return value

    def TransformToValidValGroup(self, attrName, value, *rest):
        if type(value) == types.StringType:
            valGroup = ValGroupFromString(value)
            if valGroup != None:
                return valGroup
            else:
                return getattr(self, attrName)
        return value

    '''*******************************************************
    * Formatter methods
    *******************************************************'''
    def StrikeFormatterCB(self, *args):
        return GetFXSpotForwardFormatter(self.foreignInstrument, self.domesticCurrency, False)

    def FXRateFormatterCB(self, attrName):
        return FXRateFormatter(self.foreignInstrument, self.domesticCurrency, Flipped(attrName))

    def FXRateFlipFormatterCB(self, attrName):
        formatter = FXRateInverseFormatter if self.IsDigital() else FXRateFormatter
        return formatter(self.foreignInstrument, self.domesticCurrency, self.saveTradeQuotation.endswith(self.domesticCurrency.Name()))

    def FXPointsFormatterCB(self, attrName):
        return FXPointsFormatter(self.foreignInstrument, self.domesticCurrency, Flipped(attrName))

    def StrikeFormatterInverseCB(self, *args):
        return GetFXSpotForwardFormatter(self.foreignInstrument, self.domesticCurrency, True)

    def ForeignAmountFormatterCB(self, *args):
        return AmountFormatter(self.foreignInstrument)

    def DomesticAmountFormatterCB(self, *args):
        return AmountFormatter(self.domesticCurrency)

    def SingleValueFormatterCB(self, *args):
        return SingleValueFormatter("Buy")

    '''*******************************************************
    * Label methods
    *******************************************************'''
    def BuySellLabel(self, *args):
        return self.CurrentSaveTrade().BoughtAsString()

    def BuySellHeader(self, *args):
        return self.BuySellLabel()

    def QuoteQuotationPriceLabel(self, *args):
        '''
        IsDigital() due to avoid having labels in %curr notation for prices/strikes/etc.
        '''
        return QuotationLabel(self.QuoteTrade(), self.IsDigital())

    def DomesticCurrencyLabel(self, *args):
        return CurrencyLabel(True, self.IsQuoteCallOption())

    def ForeignCurrencyLabel(self, *args):
        return CurrencyLabel(False, self.IsQuoteCallOption())

    def StrikeDomPerForLabel(self, *args):
        return self.QuoteQuotationPriceLabel()

    def ForeignAmountLabel(self, *args):
        return self.QuoteTrade().Instrument().Underlying().Name()

    def DomesticAmountLabel(self, *args):
        return self.QuoteTrade().Instrument().StrikeCurrency().Name()

    def InverseQuoteQuotationLabel(self):
        return Inverse(self.QuoteQuotationPriceLabel()) if self.IsFxOption() else ""

    def StrikeForPerDomLabel(self, *args):
        return self.InverseQuoteQuotationLabel()

    def FXRateLabel(self, attrName):
        quote = self.InverseQuoteQuotationLabel() if Flipped(attrName) else self.QuoteQuotationPriceLabel()
        return quote

    def TheorValSaveTradeLabel(self, *args):
        return 'TheorVal' + CurrencyStrFromDV(self.saveTradeCalcVal_theorVal)

    def TheorValNoPremiumSaveTradeLabel(self, *args):
        return 'TheorVal Ins' + CurrencyStrFromDV(self.saveTradeCalcVal_theorVal)

    '''*******************************************************
    * Custom calculations methods
    *******************************************************'''
    def IsPremiumAdjusted(self):
        return self.PricingOptions().CurrentSaveIsFlippedQuoteTrade() or self.PricingOptions().CurrentSaveIsAltQuoteTrade()

    def PremiumQuotedForeignTrade(self):
        return self.AltQuoteTrade() if self.IsPremiumAdjusted() else self.QuoteTrade()

    def PremiumQuotedDomesticTrade(self):
        return self.FlippedQuoteTrade() if self.IsPremiumAdjusted() else self.FlippedAltQuoteTrade()

    def CustomCalcLabel(self, *args):
        return '%s;%s' % (QuotationLabel(self.PremiumQuotedForeignTrade()), QuotationLabel(self.PremiumQuotedDomesticTrade()))

    def CustomCalcConfig(self, *args):
        return PriceGreekExcludeVolatilityMovement(None)

    def CustomCalcConfigFlipped(self, *args):
        return PriceGreekExcludeVolatilityMovement(None).Merge(DomesticColumnConfig(None))

    def GetCustomCalculation(self, attrName, columnName, flipped = None):
        if not columnName in self.customCalculations:
            raise DealPackageException('%s is not a valid custom calculation' % columnName)
        calcName = str(columnName).replace(' ', '_') + ('Flipped' if flipped else '')
        calc = self.GetCalculation(calcName)
        if not calc:
            calcObj = 'PremiumQuotedDomesticTrade' if flipped else 'PremiumQuotedForeignTrade'
            calcConfig = self.CustomCalcConfigFlipped if flipped else self.CustomCalcConfig
            self.CreateCalculation(calcName, '%s:FDealSheet:%s' % (calcObj, columnName), calcConfig)
            calc = self.GetCalculation(calcName)
        return calc

    '''*******************************************************
    * Enabled methods
    *******************************************************'''
    def AmountFieldDisabled(self, currency):
        return self.IsDigital() and self.payoutCurrency != currency

    def ForeignAmountEnabled(self, *args):
        return not self.AmountFieldDisabled(self.foreignInstrument)

    def DomesticAmountEnabled(self, *args):
        return not self.AmountFieldDisabled(self.domesticCurrency)

    def AtmVolatilityEnabled(self, *args):
        return self.valuationAddOnModel == 'Vanna Volga Pricing'

    '''*******************************************************
    * Solver methods
    *******************************************************'''
    def VolatilityParam(self, *args):
        return {'minValue':1e-10, 'maxValue':1000, 'precision':0.0001}

    def StrikeParamDomPerFor(self, attributeName):
        # TODO: Create new BarrierParam where barrier boundery is not above/below strike depending on Down/Up (Tomas)
        fwdPrice = GetFloatFromCalculation(self.quoteTradeCalcVal_fwd, self.BuySellLabel()) if self.quoteTradeCalcVal_fwd else 1.0
        return GetMaxMinBounderiesStrikeSolving(fwdPrice)

    def StrikeParamForPerDom(self, attributeName):
        fwdPrice = GetFloatFromCalculation(self.flippedQuoteTradeCalcVal_fwd, self.BuySellLabel()) if self.flippedQuoteTradeCalcVal_fwd else 1.0
        return GetMaxMinBounderiesStrikeSolving(fwdPrice)

    def UndValParam(self, attrName):
        if attrName.startswith('flipped'):
            undValAttr = 'flippedQuoteTradeCalcVal_undVal'
        else:
            undValAttr = 'quoteTradeCalcVal_undVal'
        undVal = GetFloatFromCalculation(getattr(self, undValAttr), self.BuySellLabel()) or 1
        return {'minValue':0.3*undVal, 'maxValue':3.0*undVal, 'precision':0.001}

    '''*******************************************************
    * Deal Package Interface methods
    *******************************************************'''
    def OnInit(self):
        self._premiumCurrencyChoices = DealPackageChoiceListSource()
        self._foreignInstrumentChoices = DealPackageChoiceListSource()
        self._domesticCurrencyChoices = DealPackageChoiceListSource()
        self._mirrorPortfolioChoices = DealPackageChoiceListSource()
        self._counterpartyPrfSet = 'NoInput'
        self._updateDefaultStrike = False
        self._storedPricingParameters = {'quoteTradeCalcVal_undVal':None}#,
                                         #'quoteTradeCalcVal_interestRate':None,
                                         #'flippedQuoteTradeCalcVal_interestRate':None}
                                         #'atmVolatility':None}

    def GetStoredPricingParameters(self, *args):
        return self._storedPricingParameters

    def OnSave(self, saveConfig):
        super(PairOptionsDealPackageBase, self).OnSave(saveConfig)
        if saveConfig.InstrumentPackage() == 'SaveNew':
            self.InstrumentPackage().Name('')

    def OnNew(self):
        self.SetSolverParameter(None, 'strikeDomesticPerForeign')
        self.SetDefaultStrike()
        self.SetRoundingSpecification(None, None, None, None)
        self.OverrideValuationGroup('Vanilla')

    def OnOpen(self):
        for t in self.DealPackage().Trades():
            if t.Trade().MirrorTrade() and t.MirrorPortfolio() != t.Trade().MirrorTrade().Portfolio():
                t.MirrorPortfolio(t.Trade().MirrorTrade().Portfolio())

        self.SetSolverParameter(None, 'strikeDomesticPerForeign')

    def OnCopy(self, originalDealPackage, anAspectSymbol):
        storedPricingParameters = originalDealPackage.GetAttribute('getStoredPricingParameters')()
        for attribute in self._storedPricingParameters:
            self._storedPricingParameters[attribute] = storedPricingParameters[attribute]
        self._RegisterAllObjectMappings()
        if str(anAspectSymbol) == 'solving':
            self.bidAskMode = False
        self.gridModelView = self._gridModelView_default()
        if str(anAspectSymbol) != 'solving':
            self.SetSolverParameter(None, 'strikeDomesticPerForeign')

        tradeTime = originalDealPackage.Trades().First().TradeTime()
        for t in self.PricingOptions().Trades():
            t.TradeTime(tradeTime)

    def GetDeltaTraitsList(self):
        return ['quoteTradeCalcVal_delta', 'flippedQuoteTradeCalcVal_delta']

    def IsVolatilitySimulated(self):
        return self.GetAttributeMetaData('volatility', 'isCalculationSimulated')()

    def SolverStrikeChanged(self, attribute, old, new, userInputTraitName):
        deltaTraits = self.GetDeltaTraitsList()
        if self.IsVolatilitySimulated() and self._isSolverDealPackage and self.solverTopValue in deltaTraits:
            self._calculationsRegistered = False
            self._RegisterAllCalculations()

    def OverrideValuationGroup(self, baseType):
        valuationGroupOverride = ValuationGroupOverride(baseType)
        if valuationGroupOverride:
            try:
                self.valGroup = valuationGroupOverride.ValuationGroup()
            except Exception as e:
                print ('Cannot set the Valuation Group Override', e)

    def MirrorPortfolioVisible(self, attributeName):
        counterparty = self.CurrentSaveTrade().Counterparty()
        return self.IsShowModeDetail() or self.Trade().MirrorPortfolio() or (counterparty and counterparty.OwnedPortfolios().Size())

    def MirrorPortfolioChoices(self, attributeName):
        if self._mirrorPortfolioChoices.IsEmpty():
            self.UpdateMirrorPortfolioChoices()
        return self._mirrorPortfolioChoices

    def UpdateMirrorPortfolioChoices(self, *args):
        self._mirrorPortfolioChoices.Clear()
        counterparty = self.CurrentSaveTrade().Counterparty()
        if counterparty:
            self._mirrorPortfolioChoices.AddAll(counterparty.OwnedPortfolios())

    def CounterpartyPortfolio(self, val = 'NoInput'):
        if val == 'NoInput':
            t = self.CurrentSaveTrade()
            if t.IsInfant():
                cptyPrf = t.MirrorPortfolio()
            if self._counterpartyPrfSet == 'NoInput':
                cptyPrf = t.MirrorTrade().Portfolio() if t.MirrorTrade() else None
            else:
                cptyPrf = self._counterpartyPrfSet
            return cptyPrf
        else:
            for t in self.PricingTrades():
                t.MirrorPortfolio(val)
            self._counterpartyPrfSet = val


import time
import requests
import grovepi
import sys

# Air Sensor goes into port A0
# Distance Sensor goes into port D4
# Temperature and Humidity sensor goes into port D8
# Light Sensor goes into port A2?
# The accelerometer goes into any I2C port
# SIG,NC,VCC,GND

air_sensor = 0
ultrasonic_ranger = 4
dht11_port = 2
light_sensor = 2

url = "http://RossMacbookPro.local:3000"

while True:
    try:
        # Air Sensor
        sensor_value = grovepi.analogRead(air_sensor)
        if sensor_value <= 300:
            air_quality = 'Fresh Air'
        else:
            air_quality = 'Polluted Air'

        print('Air Sensor Value',sensor_value)
        print('Air Quality',air_quality)

        # Distance Sensor
        dist_value = grovepi.ultrasonicRead(ultrasonic_ranger)

        print('Distance',dist_value)

        # Temperature and Humidity Sensor

        [temp, humi] = grovepi.dht(dht11_port, 0)

        print(temp, "C")
        print(humi, "%")

        # Light Sensor

        light_value = grovepi.analogRead(light_sensor)
        print("light_value = %d" %(light_value))

        print("Done")

        # Accelerometer

        acc_value = grovepi.acc_xyz()
        print("acc",acc_value)

        # Broadcast Payload
        payload = { 'airQuality' : air_quality, 'airValue' : sensor_value, 'distance' : dist_value, 'humi' : humi, 'temp' : temp, 'lightValue' : light_value, 'accelerometer' : acc_value}

        requests.post(url, data=payload)

        time.sleep(1)

    # Errors

    except TypeError:
        print ("Error")
    except IOError:
        print ("Error")


import datetime
import logging
from django.core.exceptions import ValidationError

from django.test import TestCase
from django.utils import timezone

from rehearsalbooking.models import OpeningHour, Organisation, Room, Schedule

logger = logging.getLogger(__name__)
tz = timezone.get_current_timezone()

class ScheduleTest(TestCase):
    def setUp(self):
        license_expires = tz.localize(datetime.datetime(year=2019, month=4, day=1))
        self.organisation = Organisation.create("test_organisation", license_expires=license_expires,email="vandermostenjonas@gmail.com",
                                           phone="0496330549")
        self.room = Room.objects.create(price_per_timeslot=5, name="test_room", organisation=self.organisation)
        self.schedule = self.room.get_main_schedule()

    def test_opening_hour_overlaps(self):
        """
        It is not possible to save a schedule that has overlapping opening hours
        """
        start_a = datetime.time(hour=10, minute=30)
        end_a = datetime.time(hour=12, minute=30)

        start_b = datetime.time(hour=11, minute=30)
        end_b = datetime.time(hour=13, minute=30)

        OpeningHour.objects.create(week_day=OpeningHour.MONDAY, start=start_a, end=end_a, schedule=self.schedule)

        with self.assertRaises(ValidationError) as error:
            OpeningHour.objects.create(week_day=OpeningHour.MONDAY,start=start_b, end=end_b, schedule=self.schedule)
        self.assertEqual(error.exception.messages[0],
                         "This schedule has overlapping opening hours")

    def test_opening_hour_overlaps_not(self):
        start_a = datetime.time(hour=10, minute=30)
        end_a = datetime.time(hour=12, minute=30)

        start_b = datetime.time(hour=13, minute=30)
        end_b = datetime.time(hour=14, minute=30)

        opening_hour_a = OpeningHour.objects.create(week_day=OpeningHour.MONDAY, start=start_a, end=end_a,
                                                    schedule=self.schedule)
        opening_hour_b = OpeningHour.objects.create(week_day=OpeningHour.MONDAY, start=start_b, end=end_b,
                                                    schedule=self.schedule)

        self.assertTrue(self.schedule.opening_hours.filter(id=opening_hour_a.id))
        self.assertTrue(self.schedule.opening_hours.filter(id=opening_hour_b.id))

    def test_opening_hour_overlaps_edges(self):
        start_a = datetime.time(hour=10, minute=30)
        end_a = datetime.time(hour=12, minute=30)

        start_b = datetime.time(hour=12, minute=30)
        end_b = datetime.time(hour=13, minute=30)

        opening_hour_a = OpeningHour.objects.create(week_day=1, start=start_a, end=end_a, schedule=self.schedule)
        opening_hour_b = OpeningHour.objects.create(week_day=1, start=start_b, end=end_b, schedule=self.schedule)

        self.assertTrue(self.schedule.opening_hours.filter(id=opening_hour_a.id))
        self.assertTrue(self.schedule.opening_hours.filter(id=opening_hour_b.id))

    def test_schedule_overlaps_same_room(self):
        start_a = tz.localize(datetime.datetime(year=2017, month=12, day=1, hour=10, minute=30))
        end_a = tz.localize(datetime.datetime(year=2017, month=12, day=10, hour=12, minute=30))

        start_b = tz.localize(datetime.datetime(year=2017, month=12, day=9, hour=11, minute=30))
        end_b = tz.localize(datetime.datetime(year=2017, month=12, day=11, hour=13, minute=30))

        Schedule.objects.create(start=start_a, end=end_a, room=self.room)
        with self.assertRaises(ValidationError) as error:
            Schedule.objects.create(start=start_b, end=end_b, room=self.room)
        self.assertEquals(error.exception.messages[0], "test_room has overlapping schedules")


# -*- coding: utf-8 -*-
from django import forms
from .models import *
from tinymce.widgets import TinyMCE

class SendMessageForm(forms.ModelForm):
    class Meta:
        model = Message
        exclude = [
            'read',
            'read_at',
            'sender',
            'receiver',
        ]
        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'body': TinyMCE(attrs={'class': 'form-control'})
        }

class MessageAttachmentsForm(forms.ModelForm):
    class Meta:
        model = Attachments
        fields = ['attachment']
        widgets = {
            'attachment': forms.FileInput(attrs={'class': 'form-control', 'multiple': 'multiple'})
        }

class ReplyMessageForm(forms.ModelForm):
    class Meta:
        model = Message
        exclude = [
            'read',
            'read_at',
            'sender',
            'receiver',
            'title',
        ]
        widgets = {
            'body': TinyMCE(attrs={'class': 'form-control'})
        }

class ForwardMessageForm(forms.ModelForm):
    class Meta:
        model = Message
        exclude = [
            'read',
            'read_at',
            'sender',
            'receiver',
            'title',
        ]
        widgets = {
            'body': TinyMCE(attrs={'class': 'form-control'})
        }


import pandas as pd

PATH_DATA = '/hartensa/data_other/hozan_S1186.csv'

def main():
    df = pd.read_csv(PATH_DATA, sep=";", converters={'Density': lambda x: float(x.replace('.', '').replace(',', '.'))},
                     header=0)
    idx_density = 7
    idx_timestamp = 1
    new_df = pd.DataFrame(df.iloc[:, idx_density].values)
    new_df.index = df.iloc[:, idx_timestamp]
    new_df.columns = ['1186']
    new_df.iloc
    new_df.to_csv('/hartensa/data_other/hozan_S1186_for_model.csv')

if __name__ == '__main__':
    main()


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import random
import numpy as np

# PyTorch imports.
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

# TensorFlow import.
import tensorflow as tf

# MXNet imports.
from mxnet import nd, autograd, init, gluon
from mxnet.gluon import data as gdata
from mxnet.gluon import nn
from mxnet.gluon import loss as gloss

np.random.seed(71)

class LinearRegression(object):
    """Numpy implementation of Linear Regression."""

    def __init__(self, batch_size=64, lr=0.01, n_epochs=1000):
        self.batch_size = batch_size
        self.lr = lr
        self.n_epochs = n_epochs

    def get_data(self, X_train, y_train, shuffle=True):
        """Get dataset and information."""
        self.X_train = X_train
        self.y_train = y_train

        # Get the numbers of examples and inputs.
        self.n_examples, self.n_inputs = self.X_train.shape

        if shuffle:
            idx = list(range(self.n_examples))
            random.shuffle(idx)
            self.X_train = self.X_train[idx]
            self.y_train = self.y_train[idx]

    def _create_weights(self):
        """Create model weights and bias."""
        self.w = np.zeros(self.n_inputs).reshape(self.n_inputs, 1)
        self.b = np.zeros(1).reshape(1, 1)

    def _model(self, X):
        """Linear regression model."""
        return np.matmul(X, self.w) + self.b

    def _loss(self, y, y_):
        """Squared error loss.

        # squared_error_loss(y, y_)
        #   = - 1/n * \sum_{i=1}^n (y_i - y__i)^2
        """
        self.squared_error = np.square(y - y_)
        return np.mean(self.squared_error)

    def _optimize(self, X, y):
        """Optimize by stochastic gradient descent."""
        m = X.shape[0]

        y_ = self._model(X)
        dw = 1 / m * np.matmul(X.T, y_ - y)
        db = np.mean(y_ - y)

        for (param, grad) in zip([self.w, self.b], [dw, db]):
            param[:] = param - self.lr * grad

    def _fetch_batch(self):
        """Fetch batch dataset."""
        idx = list(range(self.n_examples))
        for i in range(0, self.n_examples, self.batch_size):
            idx_batch = idx[i:min(i + self.batch_size, self.n_examples)]
            yield (self.X_train.take(idx_batch, axis=0),
                   self.y_train.take(idx_batch, axis=0))

    def fit(self):
        """Fit model."""
        self._create_weights()

        for epoch in range(self.n_epochs):
            total_loss = 0
            for X_train_b, y_train_b in self._fetch_batch():
                y_train_b = y_train_b.reshape((y_train_b.shape[0], -1))
                self._optimize(X_train_b, y_train_b)
                batch_loss = self._loss(y_train_b, self._model(X_train_b))
                total_loss += batch_loss * X_train_b.shape[0]

            if epoch % 100 == 0:
                print('epoch {0}: training loss {1}'
                      .format(epoch, total_loss / self.n_examples))

        return self

    def get_coeff(self):
        """Get model coefficients."""
        return self.b, self.w.reshape((-1,))

    def predict(self, X):
        """Predict for new data."""
        return self._model(X).reshape((-1,))

class LinearRegressionTorch(nn.Module):
    """PyTorch implementation of Linear Regression."""

    def __init__(self, batch_size=64, lr=0.01, n_epochs=1000):
        super(LinearRegressionTorch, self).__init__()
        self.batch_size = batch_size
        self.lr = lr
        self.n_epochs = n_epochs

    def get_data(self, X_train, y_train, shuffle=True):
        """Get dataset and information."""
        self.X_train = X_train
        self.y_train = y_train

        # Get the numbers of examples and inputs.
        self.n_examples, self.n_inputs = self.X_train.shape

        if shuffle:
            idx = list(range(self.n_examples))
            random.shuffle(idx)
            self.X_train = self.X_train[idx]
            self.y_train = self.y_train[idx]

    def _create_model(self):
        """Create linear regression model."""
        self.model = nn.Linear(self.n_inputs, 1)

    def forward(self, x):
        """Foward to output model."""
        y = self.model(x)
        return y

    def _create_loss(self):
        """Create squared error loss."""
        self.criterion = nn.MSELoss()

    def _create_optimizer(self):
        """Create optimizer by stochastic gradient descent."""
        self.optimizer = optim.SGD(self.model.parameters(), lr=self.lr)

    def build_graph(self):
        """Build computational graph."""
        self._create_model()
        self._create_loss()
        self._create_optimizer()

    def _fetch_batch(self):
        """Fetch batch dataset."""
        idx = list(range(self.n_examples))
        for i in range(0, self.n_examples, self.batch_size):
            idx_batch = idx[i:min(i + self.batch_size, self.n_examples)]
            yield (self.X_train.take(idx_batch, axis=0),
                   self.y_train.take(idx_batch, axis=0))

    def fit(self):
        """Fit model."""
        for epoch in range(1, self.n_epochs + 1):
            total_loss = 0
            for X_train_b, y_train_b in self._fetch_batch():
                # Convert to Tensor from NumPy array and reshape ys.
                X_train_b, y_train_b = (
                    torch.from_numpy(X_train_b),
                    torch.from_numpy(y_train_b).view(-1, 1))

                y_pred_b = self.model(X_train_b)
                batch_loss = self.criterion(y_pred_b, y_train_b)
                total_loss += batch_loss * X_train_b.shape[0]

                # Zero grads, performs backward pass, and update weights.
                self.optimizer.zero_grad()
                batch_loss.backward()
                self.optimizer.step()

            if epoch % 100 == 0:
                print('Epoch {0}: training loss: {1}'
                      .format(epoch, total_loss / self.n_examples))

    def get_coeff(self):
        """Get model coefficients."""
        # Detach var which require grad.
        return (self.model.bias.detach().numpy(),
                self.model.weight.detach().numpy())

    def predict(self, X):
        """Predict for new data."""
        with torch.no_grad():
            X_ = torch.from_numpy(X)
            return self.model(X_).numpy().reshape((-1,))

def reset_tf_graph(seed=71):
    """Reset default TensorFlow graph."""
    tf.reset_default_graph()
    tf.set_random_seed(seed)
    np.random.seed(seed)

class LinearRegressionTF(object):
    """A TensorFlow implementation of Linear Regression."""

    def __init__(self, batch_size=64, learning_rate=0.01, n_epochs=1000):
        self.batch_size = batch_size
        self.n_epochs = n_epochs
        self.learning_rate = learning_rate

    def get_data(self, X_train, y_train, shuffle=True):
        """Get dataset and information.s"""
        self.X_train = X_train
        self.y_train = y_train

        # Get the numbers of examples and inputs.
        self.n_examples, self.n_inputs = self.X_train.shape

        idx = list(range(self.n_examples))
        if shuffle:
            random.shuffle(idx)
        self.X_train = self.X_train[idx]
        self.y_train = self.y_train[idx]

    def _create_placeholders(self):
        """Create placeholder for features and response."""
        self.X = tf.placeholder(tf.float32, shape=(None, self.n_inputs), name='X')
        self.y = tf.placeholder(tf.float32, shape=(None, 1), name='y')

    def _create_weights(self):
        """Create and initialize model weights and bias."""
        self.w = tf.get_variable(shape=[self.n_inputs, 1],
                                 initializer=tf.random_normal_initializer(),
                                 name='weights')
        self.b = tf.get_variable(shape=[1],
                                 initializer=tf.zeros_initializer(),
                                 name='bias')

    def _model(self, X):
        """Linear regression model."""
        return tf.matmul(X, self.w) + self.b

    def _create_model(self):
        """Create linear model."""
        self.y_ = self._model(self.X)

    def _create_loss(self):
        # Create mean squared error loss.
        self.loss = tf.reduce_mean(tf.square(self.y_ - self.y), name='loss')

    def _create_optimizer(self):
        # Create gradient descent optimization.
        self.optimizer = (
            tf.train.GradientDescentOptimizer(learning_rate=self.learning_rate)
            .minimize(self.loss))

    def build_graph(self):
        """Build computational graph."""
        self._create_placeholders()
        self._create_weights()
        self._create_model()
        self._create_loss()
        self._create_optimizer()

    def _fetch_batch(self):
        """Fetch batch dataset."""
        idx = list(range(self.n_examples))
        for i in range(0, self.n_examples, self.batch_size):
            idx_batch = idx[i:min(i + self.batch_size, self.n_examples)]
            yield (self.X_train[idx_batch, :], self.y_train[idx_batch].reshape(-1, 1))

    def fit(self):
        """Fit model."""
        saver = tf.train.Saver()

        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())

            for epoch in range(1, self.n_epochs + 1):
                total_loss = 0
                for X_train_b, y_train_b in self._fetch_batch():
                    feed_dict = {self.X: X_train_b, self.y: y_train_b}
                    _, batch_loss = sess.run([self.optimizer, self.loss],
                                             feed_dict=feed_dict)
                    total_loss += batch_loss * X_train_b.shape[0]

                if epoch % 100 == 0:
                    print('Epoch {0}: training loss: {1}'
                          .format(epoch, total_loss / self.n_examples))

            # Save model.
            saver.save(sess, 'checkpoints/linreg')

    def get_coeff(self):
        """Get model coefficients."""
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            # Load model.
            saver = tf.train.Saver()
            saver.restore(sess, 'checkpoints/linreg')
            return self.b.eval(), self.w.eval().reshape((-1,))

    def predict(self, X):
        """Predict for new data."""
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            # Load model.
            saver = tf.train.Saver()
            saver.restore(sess, 'checkpoints/linreg')
            return self._model(X).eval().reshape((-1,))

def main():
    import sklearn
    from sklearn.datasets import fetch_california_housing
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import MinMaxScaler
    from sklearn.linear_model import LinearRegression as LinearRegressionSklearn
    from metrics import mean_squared_error

    # Read California housing data.
    housing = fetch_california_housing()
    data = housing.data
    label = housing.target

    # Normalize features first.
    scaler = StandardScaler()
    data = scaler.fit_transform(data)

    # Split data into training and test datasets.
    X_train_raw, X_test_raw, y_train, y_test = train_test_split(
        X, y, test_size=0.25, random_state=71, shuffle=True)

    # Feature engineering for standardizing features by min-max scaler.
    min_max_scaler = MinMaxScaler()
    X_train = min_max_scaler.fit_transform(X_train_raw)
    X_test = min_max_scaler.transform(X_test_raw)

    # Convert arrays to float32.
    X_train, X_test, y_train, y_test = (
        np.float32(X_train), np.float32(X_test),
        np.float32(y_train), np.float32(y_test)
    )

    # Train Numpy linear regression model.
    linreg = LinearRegression(batch_size=64, lr=0.1, n_epochs=1000)
    linreg.get_data(X_train, y_train, shuffle=True)
    linreg.fit()
    print(linreg.get_coeff())
    y_train_ = linreg.predict(X_train)
    print('Training mean squared error: {}'
           .format(mean_squared_error(y_train, y_train_)))
    y_test_ = linreg.predict(X_test)
    print('Test mean squared error: {}'
           .format(mean_squared_error(y_test, y_test_)))

    # Train PyTorch linear regression model.
    linreg_torch = LinearRegressionTorch(batch_size=64, lr=0.1, n_epochs=1000)
    linreg_torch.get_data(X_train, y_train, shuffle=True)
    linreg_torch.build_graph()
    linreg_torch.fit()
    print(linreg_torch.get_coeff())
    y_train_ = linreg_torch.predict(X_train)
    print('Training mean squared error: {}'
           .format(mean_squared_error(y_train, y_train_)))
    y_test_ = linreg_torch.predict(X_test)
    print('Test mean squared error: {}'
           .format(mean_squared_error(y_test, y_test_)))

    # Train TensorFlow linear regression model.
    linreg_tf = LinearRegressionTF(
        batch_size=64, learning_rate=0.1, n_epochs=1000)
    linreg_tf.get_data(X_train, y_train, shuffle=True)
    linreg_tf.fit()
    print(linreg_tf.get_coeff())
    y_train_ = linreg_tf.predict(X_train)
    print('Training mean squared error: {}'
           .format(mean_squared_error(y_train, y_train_)))
    y_test_ = linreg_tf.predict(X_test)
    print('Test mean squared error: {}'
           .format(mean_squared_error(y_test, y_test_)))

    # Benchmark with sklearn's linear regression model.
    linreg_sk = LinearRegressionSklearn()
    linreg_sk.fit(X_train, y_train)
    y_train_ = linreg_sk.predict(X_train)
    print('Training mean squared error: {}'
           .format(mean_squared_error(y_train, y_train_)))
    y_test_ = linreg_sk.predict(X_test)
    print('Test mean squared error: {}'
           .format(mean_squared_error(y_test, y_test_)))

if __name__ == '__main__':
    main()


#Menampilkan Integer
print(600)

#Looping dengan for
for countdown in 5, 4, 3, 2, 1, "hey!":
    print(countdown)

#Kumpulan string di dalam variabel list
cliches = [
    "At the end of the day",
    "Having said that",
    "The fact of the matter is",
    "Be that as it may",
    "The bottom line is",
    "If you will",
    ]

#Menampilkan list dengan index ke 3
print(cliches[3],type(cliches))

#String formatting
language = 7
print("Language %s: I am Python. What's for supper?" % language)

#alternatif dengan tuple formating
print("Language {}: I am Python. What's for supper?".format(language))

#Dictionary yang menyimpan key dan value
#Dimulai dengan kurung kurawal
quotes = {
    "Moe": "A wise guy, huh?",
    "Larry": "Ow!",
    "Curly": "Nyuk nyuk!",
    }
stooge = "Curly"
print(stooge, " says: ", quotes[stooge],type(quotes))


import xml.etree.ElementTree as ET
from shutil import copy2

import sys, os.path
datapath = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..") + '/OA Data Files')
sys.path.append(datapath)

import app_config

import Base_Manage_Data
import Food
import List_Object
import GUI_Equipment_Controller

class Manage_food(Base_Manage_Data.Manage_data):
    def save_one(self,item,filename=None,backup_filename=None):
        if type(item) == Food.Food and not(item.isempty()):
            super().save_one(item,filename,backup_filename)
        else:
            raise ValueError('expected Food object, instead got ' + str(type(item)))

    def remove_item(self,item):
        if type(item) == Food.Food and not(item.isempty()):
            super().remove_item(item)
        else:
            raise ValueError('expected Food object, instead got ' + str(type(item)))

    def save_all(self,filename=None,backup_filename=None):
        if not self.current_set == self.loaded_set:
            data=ET.Element('food')
            for mfood in self.current_set.all_items:
                l=ET.SubElement(data,'foodType')
                ET.SubElement(l,'name').text = mfood.name
                ET.SubElement(l,'shortDescription').text = mfood.short_description
                ET.SubElement(l,'description').text = mfood.description
                ET.SubElement(l,'value').text = mfood.value
                ET.SubElement(l,'weight').text = mfood.weight
                ET.SubElement(l,'health').text = mfood.health
                ET.SubElement(l,'capacity').text = mfood.capacity
                ET.SubElement(l,'special').text = mfood.special
            if filename == None:
                filename = app_config.file_path + app_config.food_filename
            if backup_filename == None:
                backup_filename = app_config.backup_file_path + app_config.backup_food_filename
            copy2(filename,backup_filename)
            f = open(filename,'w')
            f.write(ET.tostring(data, encoding="unicode"))
            f.close()

    def set_controller(self,parent=None):
        self.edit_controller = GUI_Equipment_Controller.GUI_equipment_controller(parent)

    def launch_edit(self,name,parent=None):
        self.edit_controller.create_form(parent)
        if len(name) > 0:
            food = self.current_set.get_item(name)
        else:
            food = Food.Food('','')
        self.edit_controller.load_data('Food',food,self.save_one,self.close_edit_item)

    def load_set(self,filename=None):
        self.current_set = Food.Foods()
        if filename == None:
            filename = app_config.file_path + app_config.food_filename
        tree = ET.parse(filename)
        data_root = tree.getroot()
        for food in data_root:
            new_food_name = food.find('name').text or 'UNKNOWN'
            new_food_short_description = food.find('shortDescription').text or 'UNKNOWN'
            new_food = Food.Food(new_food_name,new_food_short_description)
            new_food.description = food.find('description').text or 'UNKNOWN'
            new_food.value = food.find('value').text or 0
            new_food.weight = food.find('weight').text or 0
            new_food.health = food.find('health').text or 0
            new_food.capacity = food.find('capacity').text or 0
            new_food.special = food.find('special').text or 'UNK'
            self.current_set.add_new(new_food)
        self.loaded_set = self.current_set.clone()

    def __init__(self):
        self.name = 'Food'
        Base_Manage_Data.Manage_data.__init__(self)

if __name__ == '__main__':
    manager = Manage_food()
    manager.load_food()
    manager.launch_food_list()


"""
q = multiprocessing.Queue()
q.put()  # 放入数据，获取队列满时阻塞
q.put_nowait()  # 放入数据，获取队列满时异常
q.get()  # 获取数据，获取队列空时堵塞
q.get_nowait()  # 获取数据，获取队列空时异常
q.full()
q.empty()
"""
import multiprocessing
import time

def put_data(queue):
    # print("---in get_data--id(queue) = ", id(queue))
    data = [11, 22, 33, 44]
    for temp in data:
        queue.put(temp)
    print("----存放数据到队列完成----")

def get_data(queue):
    # print("---in get_data--id(queue) = ", id(queue))
    data_list = list()
    while True:
        data = queue.get()
        data_list.append(data)
        if queue.empty():
            break
    print("---从队列获取数据完成---")
    print(data_list)

def main():
    # 创建一个Queue
    q = multiprocessing.Queue()
    # print("---in main--id(q) = ", id(q))
    # 创建多个进程，将Queue的引用当作实参传递到进程里
    p1 = multiprocessing.Process(target=put_data, args=(q,))
    p2 = multiprocessing.Process(target=get_data, args=(q,))
    p1.start()
    time.sleep(1)
    p2.start()

if __name__ == '__main__':
    main()


import cv2
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import os

def truncate_2(x):
    neg = ((x + 2) + abs(x + 2)) / 2 - 2
    return -(-neg + 2 + abs(- neg + 2)) / 2 + 2

def NoiseMap(image):
    q = [4.0, 12.0, 2.0]
    filter1 = [[0, 0, 0, 0, 0],
               [0, -1, 2, -1, 0],
               [0, 2, -4, 2, 0],
               [0, -1, 2, -1, 0],
               [0, 0, 0, 0, 0]]
    filter2 = [[-1, 2, -2, 2, -1],
               [2, -6, 8, -6, 2],
               [-2, 8, -12, 8, -2],
               [2, -6, 8, -6, 2],
               [-1, 2, -2, 2, -1]]
    filter3 = [[0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0],
               [0, 1, -2, 1, 0],
               [0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0]]
    filter1 = np.asarray(filter1, dtype=float) / q[0]
    filter2 = np.asarray(filter2, dtype=float) / q[1]
    filter3 = np.asarray(filter3, dtype=float) / q[2]

    filter_res1 = cv2.filter2D(image, -1, filter1, borderType=cv2.BORDER_REFLECT)
    filter_res2 = cv2.filter2D(image, -1, filter2, borderType=cv2.BORDER_REFLECT)
    filter_res3 = cv2.filter2D(image, -1, filter3, borderType=cv2.BORDER_REFLECT)

    tr_1 = truncate_2(filter_res1)
    tr_2 = truncate_2(filter_res2)
    tr_3 = truncate_2(filter_res3)

    res = np.array([tr_1, tr_2, tr_3])
    res = np.round(res)
    res[res > 2] = 2
    res[res < -2] = -2

    res = np.moveaxis(res, 0, -1)

    return res

if __name__ == '__main__':

    original_path = r'/mnt/zhengwen/new_trial/BOSSbase_resize'
    stego_path = r'/mnt/zhengwen/new_trial/BOSSbase_S_UNIWARD_05'

    image_names = os.listdir(original_path)
    image_names.sort(key=lambda x: int(x[:-4]))

    count = 0
    ori_images = []
    stego_images = []
    for image_name in image_names:
        print(count)
        ori_image = cv2.imread(os.path.join(original_path, image_name), 0)
        stego_image = cv2.imread(os.path.join(stego_path, image_name), 0)
        count += 1
        ori_images.append(ori_image)
        stego_images.append(stego_image)

        # if count == 200: break

    ori_images = np.array(ori_images).astype("double")
    stego_images = np.array(stego_images).astype("double")

    count = 0
    ori_noise_map = []
    for each_image in ori_images:
        ori_noise_map.append(NoiseMap(each_image))
        count += 1
        print(count)

    count = 0
    steg_noise_map = []
    for each_image in stego_images:
        steg_noise_map.append(NoiseMap(each_image))
        count += 1
        print(count)

    np.save(r"/mnt/zhengwen/new_trial/ori_noise_map.npy", ori_noise_map)
    np.save(r"/mnt/zhengwen/new_trial/steg_noise_map.npy", steg_noise_map)


# -*- coding: utf-8 -*-
"""
Created on Tue Jan 29 17:23:07 2019

@author: rezas
"""

import nltk
import re
import pprint
from nltk import Tree

my_corpus = ""

with open('movie_lines.txt', 'r') as myfile:
    my_corpus = myfile.read().replace('\n', '')

grammar = """
    NP:    {<DT><WP><VBP>*<RB>*<VBN><IN><NN>}
           {<NN|NNS|NNP|NNPS><IN>*<NN|NNS|NNP|NNPS>+}
           {<JJ>*<NN|NNS|NNP|NNPS><CC>*<NN|NNS|NNP|NNPS>+}
           {<JJ>*<NN|NNS|NNP|NNPS>+}

    """

NPChunker = nltk.RegexpParser(grammar)

def prepare_text(input):
     tokenized_sentence = nltk.sent_tokenize(input)  # Tokenize the text into sentences.
     tokenized_words = [nltk.word_tokenize(sentence) for sentence in tokenized_sentence]  # Tokenize words in sentences.
     tagged_words = [nltk.pos_tag(word) for word in tokenized_words]  # Tag words for POS in each sentence.
     word_tree = [NPChunker.parse(word) for word in tagged_words]  # Identify NP chunks
     return word_tree  # Return the tagged & chunked sentences.

sentences = prepare_text(my_corpus)
#for tree in sentences:
#    tree.draw()

def return_a_list_of_NPs(sentences):
    nps = []  # an empty list in which to NPs will be stored.
    for sent in sentences:
        tree = NPChunker.parse(sent)
        for subtree in tree.subtrees():
            if subtree.label() == 'NP':
                t = subtree
                t = ' '.join(word for word, tag in t.leaves())
                nps.append(t)
    return nps

print(return_a_list_of_NPs(sentences))


import matplotlib.pyplot as plt

file = open('./train_details/train_details_m68_5r3.txt')
# file = open('./train_details/0.txt')
data = file.readlines()
para_1 = []
para_2 = []
para_3 = []

for num in data:
    para_1.append(float(num.split(' ')[0]))
    para_2.append(float(num.split(' ')[1]))
    if float(num.split(' ')[2])<100:
        para_3.append(float(num.split(' ')[2]))

para_x=[]
for i in range(1,len(data)+1):
    para_x.append(int(i))

plt.plot(para_x,para_1,label='location')
plt.plot(para_x,para_2,label='classification')
plt.plot(para_3,label='landmarks')
plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=0, ncol=3, mode="expand", borderaxespad=0.)
plt.show()