Example #1
0
def SQL_Distance(slat1, slon1, slat2, slon2):
    # Find the Geo-distance between two pairs of latitude and longitude coords
    # Logic: Great Circle formula on a spherical Earth
    if isNull(slat1) or isNull(slon1) or isNull(slat2) or isNull(slon2):
           return ""
    try:
        lat1 = float(slat1)
        lon1 = float(slon1)
        lat2 = float(slat2)
        lon2 = float(slon2)
        R = 3956 # Earth Radius in miles
        dLat = math.radians(lat2 - lat1) # Convert Degrees 2 Radians
        dLon = math.radians(lon2 - lon1)
        lat1 = math.radians(lat1)
        lat2 = math.radians(lat2)
        a = math.sin(dLat/2) * math.sin(dLat/2) + math.sin(dLon/2) * math.sin(dLon/2) * math.cos(lat1) * math.cos(lat2)
        c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
        Results = R * c
        return str(int(round(Results)))
    except ValueError:
        return ""
    except:
        print "Unexpected error in SQL_Distance:"
        print "slat1 = " + str(slat1)
        print "slon1 = " + str(slon1)
        print "slat2 = " + str(slat2)
        print "slon2 = " + str(slon2)
        raise
Example #2
0
    def CleanDeal(self, sFICO, pLTV, sTerm):
        # This function will clean up the sFICO, pLTV, and sTerm
        # parameters, so they can be used to find APR and Monthly payment
        # If uncleanable, return 0-0-0; else, return Fico-LTV-Term
        # The returned values will correspond to a grid point on the
        # tabulated APRGrid and MonthlyGrid dictionaries
        try:
            if isNull(sFICO):
                FICO = self.LowFico
            else:
                FICO = max(self.LowFico, min(self.HighFico, float(sFICO)))
                FICO = int(round((FICO - self.LowFico)/self.StepFico) *
                            self.StepFico + self.LowFico)

            LTV = max(self.LowLTV, min(self.HighLTV, 100.0 * pLTV))
            LTV = int(round((LTV - self.LowLTV)/self.StepLTV) *
                        self.StepLTV + self.LowLTV)

            Term = int(fixNull(sTerm, cfg.TermWanted))
            if (Term < self.LowTerm) or (Term > self.HighTerm) or \
                ( (Term - self.LowTerm) % self.StepTerm != 0):
                    return (0, 0, 0)

            return (FICO, LTV, Term)
        except ValueError:
            return (0, 0, 0)
        except:
            print "Unexpected error in CleanDeal:"
            print "sFICO = " + str(sFICO)
            print "pLTV = " + str(pLTV)
            print "sTerm = " + str(sTerm)
            raise
Example #3
0
    def __init__(self, OriginZip):
        # The process of creating a new member of the ConsumerInfo class
        # takes one, optional, parameter: The Zip code of the consumer.
        # It is intended that this code will be surmised from the
        # connectivity mechanism of the browser GET query.  If not available,
        # it will default to the global cfg.DefaultZip (90650)
        self.ConsumerID = str(sha.new(repr(time.time())).hexdigest())
        self.CreateTime = time.time()
        self.CreateTimeStamp = time.asctime()
        self.LastAccessed = self.CreateTime
        self.LastAccessedTimeStamp = self.CreateTimeStamp
        self.Message = "New Session (Logged Out)"
        self.username = ""
        self.loggedIn = "N"

        self.Zip = UserField("Zip Code")
        self.Zip.isFocus = True
        if isNull(OriginZip):
            self.Zip.Value = cfg.DefaultZip
            self.Zip.GuessBasis = "Global Default Zip"
        else:
            self.Zip.Value = OriginZip
            self.Zip.GuessBasis = "Origin Zip"

        self.Fico = UserField("FICO Score")
        self.Income = UserField("Monthly Gross Income")
        self.DebtService = UserField("Monthly Expenses")
        self.isHomeowner = UserField("Homeowner?")
        self.isCosigner = UserField("Co-Signer Available?")
        self.Cosigner = UserField("Co-Signer FICO")
        self.isTradeIn = UserField("Trade-In Available?")
        self.TradeInValue = UserField("Trade-In Value")
        self.TradeInPayoff = UserField("Trade-In Loan Payoff")
        self.UpfrontWant = UserField("Down Payment Wanted")
        self.UpfrontMax = UserField("Down Payment Maximum")
        self.MonthlyWant = UserField("Monthly Payment Wanted")
        self.MonthlyMax = UserField("Monthly Payment Maximum")
        self.TermWant = UserField("Loan Term (months) Wanted")

        self.Latitude = UserField("Latitude")
        self.Longitude = UserField("Longitude")
        self.TaxRate = UserField("Sales Tax Rate")
        self.TradeInTaxCredit = UserField("Sales Tax Credit for Trade-In")

        self.MakeGuesses()
Example #4
0
    def MakeGuesses(self):
        # This is the main code section for affecting system guesses.
        # It is a method applied against members of the ConsumerInfo class.
        # When this method is called, all data fields that are not user-entered
        #   (isGuess = True) will be (re)evaluated in light of all other
        #   information so as to make the best guesses possible
        # In general, only fields with isGuess = True are affected;
        #   However, in some situation even entered values (isGuess = False)
        #   are overridden (for example if a Maximum is set below the ideal)
        # Also, entered values that fail data validity checking are cleared
        #   and revert to guess status
        #
        # This method requires a prepared MyZip (MyZIP, the only member of
        #   the byZIP class should be initialized prior to the first call to
        #   MakeGuesses, and used each time).
        #
        # The following logic is used to generate guesses:
        # ------------------------------------------------
        #   Zip: Use global default (cfg.DefaultZip = 90650)
        #
        #   Latitude, Longitude, TaxRate, TradeInTaxCredit: Lookup from Zip
        #       (note: latitude, Longitude, TaxRate, TradeInTaxCredit get the
        #       same isGuess status as zip)
        #
        #   Fico: If no actual Income was provided, lookup table from Zip
        #           If income is provided, apply income->fico model
        #           the model uses a linear fit from income to fico and then
        #           modifies that fit with a US-State-specific offset
        #           The final result is rounded, lower-, and upper- bounded.
        #             The following global parameters define the model
        #             cfg.SlopeFicoFromIncome = 0.00074811*12
        #             cfg.InterceptFicoFromIncome = 657.7013707
        #             cfg.LowestFicoFromIncome = 640
        #             cfg.HighstFicoFromIncome = 800
        #             cfg.FicoRound = 1
        #
        #   Income: If no actual Fico was provided, lookup from Zip
        #           If fico is provided, apply income->fico model in reverse
        #           The final result is rounded, lower-, and upper- bounded.
        #             cfg.LowestIncomeFromFico = 2500
        #             cfg.HighstIncomeFromFico = 7500
        #             cfg.IncomeRound = 100
        #
        #   DebtService: 10% of Income (actual or guessed), rounded to nearest $25
        #
        #   isHomeOwner: Guess is always "N"
        #
        #   isCosigner: If there is an actual entry for Cosigner, then
        #                   isCosigner is set to "Y" and the entry is not
        #                   considered a guess (isCosigner.isGuess = False)
        #               Otherwise, isCosigner is set to "N"
        #
        #   Cosigner: If isCosigner (actual or guessed) is "N" then set to ""
        #               Otherwise, use the Zip Fico lookup table
        #
        #   isTradeIn: If there is an actual entry for either TradeInValue or
        #               TradeInPayoff, then isTRadeIn is set to "Y" and the
        #               entry is nor considered a guess (isTradeIn.isGuess = False)
        #               Otherwise, isTradeIn is set to "N"
        #
        #   TradeInValue: If isTradeIn is "N" then set to ""
        #                   Otherwise, 2.0 * Monthly Income rounded to nearest $500
        #                   note: If a value was entered for TradeInPayoff,
        #                   then isTradeIn will automatically set to "Y",
        #                   which will trigger then income-based computation
        #
        #   TradeInPayoff: If isTradeIn is "N" then set to ""
        #                   Otherwise, $0 (will be updated)
        #
        #   UpfrontWant: If UpfrontMax is entered, use that number
        #                   else, Set to 1.0 * Month Income (actual or guess),
        #                   between $0 and $5000, rounded to nearest $100
        #
        #   UpfrontMax: If UpfrontWant is entered, use that number
        #                   else, Set to 2.0 * Month Income (actual or guess),
        #                   between $2000 and $20,000, rounded to nearest $100
        #               If both UpfrontWant and UpfrontMax are entered, and
        #                   UpfrontMax < UpfrontWant (not a logical entry),
        #                   then UpfrontMax is overwritten with UpfrontWant
        #
        #   MonthlyWant: If MonthlyMax is entered, use that number
        #                   else, Set to 8% * Month Income (actual or guess),
        #                   between $100 and $2500, rounded to nearest $10
        #
        #   MonthlyMax: If MonthlyWant is entered, use that number
        #                   else, Set to 18% * Month Income (actual or guess),
        #                   between $200 and $5000, rounded to nearest $10
        #               If both MonthlyWant and MonthlyMax are entered, and
        #                   MonthlyMax < MonthlyWant (not a logical entry),
        #                   then MonthlyMax is overwritten with MonthlyWant
        #
        #   TermWant:   Guess is always 72

        ###### DATA VALIDATION FOR ALL USER ENTERED FIELDS #####
        self.Zip.isGuess = self.Zip.isGuess or \
                            (self.Zip.Value not in MyZip.Income)

        self.Fico.Value = strRound(self.Fico.Value,
                                      1,
                                      cfg.LowestFicoAnywhere,
                                      cfg.HighestFicoAnywhere)
        self.Fico.isGuess = self.Fico.isGuess or isNull(self.Fico.Value)

        self.Income.Value = strRound(self.Income.Value,
                                      1,
                                      cfg.LowestIncomeAnywhere,
                                      cfg.HighestIncomeAnywhere)
        self.Income.isGuess = self.Income.isGuess or isNull(self.Income.Value)

        self.DebtService.Value = strRound(self.DebtService.Value,
                                          1,
                                          cfg.LowestIncomeAnywhere,
                                          cfg.HighestIncomeAnywhere)
        self.DebtService.isGuess = self.DebtService.isGuess or isNull(self.DebtService.Value)


        self.Cosigner.Value = strRound(self.Cosigner.Value,
                                          1,
                                          cfg.LowestFicoAnywhere,
                                          cfg.HighestFicoAnywhere)
        self.Cosigner.isGuess = self.Cosigner.isGuess or isNull(self.Cosigner.Value)

        self.TradeInValue.Value = strRound(self.TradeInValue.Value,
                                              1,
                                              cfg.LowestTradeInAnywhere,
                                              cfg.HighestTradeInAnywhere)
        self.TradeInValue.isGuess = self.TradeInValue.isGuess or isNull(self.TradeInValue.Value)

        self.TradeInPayoff.Value = strRound(self.TradeInPayoff.Value,
                                              1,
                                              cfg.LowestTradeInAnywhere,
                                              cfg.HighestTradeInAnywhere)
        self.TradeInPayoff.isGuess = self.TradeInPayoff.isGuess or isNull(self.TradeInPayoff.Value)

        self.UpfrontWant.Value = strRound(self.UpfrontWant.Value,
                                              1,
                                              cfg.LowestUpfrontAnywhere,
                                              cfg.HighestUpfrontAnywhere)
        self.UpfrontWant.isGuess = self.UpfrontWant.isGuess or isNull(self.UpfrontWant.Value)

        self.UpfrontMax.Value = strRound(self.UpfrontMax.Value,
                                              1,
                                              cfg.LowestUpfrontAnywhere,
                                              cfg.HighestUpfrontAnywhere)
        self.UpfrontMax.isGuess = self.UpfrontMax.isGuess or isNull(self.UpfrontMax.Value)

        self.MonthlyWant.Value = strRound(self.MonthlyWant.Value,
                                              1,
                                              cfg.LowestMonthlyAnywhere,
                                              cfg.HighestMonthlyAnywhere)
        self.MonthlyWant.isGuess = self.MonthlyWant.isGuess or isNull(self.MonthlyWant.Value)

        self.MonthlyMax.Value = strRound(self.MonthlyMax.Value,
                                              1,
                                              cfg.LowestMonthlyAnywhere,
                                              cfg.HighestMonthlyAnywhere)
        self.MonthlyMax.isGuess = self.MonthlyMax.isGuess or isNull(self.MonthlyMax.Value)

        self.TermWant.Value = strRound(self.TermWant.Value,
                                              cfg.TermRound,
                                              cfg.LowestTermAnywhere,
                                              cfg.HighestTermAnywhere)
        self.TermWant.isGuess = self.TermWant.isGuess or isNull(self.TermWant.Value)

        ###### SYSTEM GUESS ALGORITHMS BEGIN HERE #####
        if self.Zip.isGuess:
            self.Zip.Value = cfg.DefaultZip
            self.Zip.GuessBasis = "Default Zip Code"

        self.Latitude.Value = MyZip.Latitude[self.Zip.Value]
        self.Latitude.isGuess = self.Zip.isGuess
        self.Latitude.GuessBasis = "Table lookup from Zip"

        self.Longitude.Value = MyZip.Longitude[self.Zip.Value]
        self.Longitude.isGuess = self.Zip.isGuess
        self.Longitude.GuessBasis = "Table lookup from Zip"

        self.TaxRate.Value = MyZip.TaxRate[self.Zip.Value]
        self.TaxRate.isGuess = self.Zip.isGuess
        self.TaxRate.GuessBasis = "Table lookup from Zip"

        self.TradeInTaxCredit.Value = MyZip.TradeInTaxCredit[self.Zip.Value]
        self.TradeInTaxCredit.isGuess = self.Zip.isGuess
        self.TradeInTaxCredit.GuessBasis = "Table lookup from Zip"


        if self.Fico.isGuess:
            if self.Income.isGuess:
                self.Fico.Value = strRound(
                                  MyZip.FICO3[self.Zip.Value],
                                  cfg.FicoRound,
                                  cfg.LowestFicoAnywhere,
                                  cfg.HighestFicoAnywhere)
                self.Fico.GuessBasis = "from Zip-based model"
            else:
                self.Fico.Value = strRound(
                                  max(cfg.LowestFicoFromIncome,
                                  min(cfg.HighstFicoFromIncome,
                                      cfg.SlopeFicoFromIncome *
                                      float(self.Income.Value) +
                                      cfg.InterceptFicoFromIncome +
                                      MyZip.ST2offset[self.Zip.Value])),
                                      cfg.FicoRound,
                                      cfg.LowestFicoAnywhere,
                                      cfg.HighestFicoAnywhere)
                self.Fico.GuessBasis = "from ACTUAL Income, offset by State"

        if self.Income.isGuess:
            if self.Fico.isGuess:
                self.Income.Value = strRound(MyZip.Income[self.Zip.Value],
                                             cfg.IncomeRound,
                                             cfg.LowestIncomeAnywhere,
                                             cfg.HighestIncomeAnywhere)
                self.Income.GuessBasis = "from Zip Median table"
            else:
                self.Income.Value = strRound(
                                    max(cfg.LowestIncomeFromFico,
                                    min(cfg.HighstIncomeFromFico,
                                        (float(self.Fico.Value) -
                                         MyZip.ST2offset[self.Zip.Value] -
                                         cfg.InterceptFicoFromIncome) /
                                        cfg.SlopeFicoFromIncome)),
                                    cfg.IncomeRound,
                                    cfg.LowestIncomeAnywhere,
                                    cfg.HighestIncomeAnywhere)
                self.Income.GuessBasis = "from ACTUAL FICO, offset by State"

        if self.DebtService.isGuess:
            self.DebtService.Value = strRound(
                                      float(self.Income.Value) *
                                      cfg.DebtPercentofIncome,
                                      cfg.DebtRound,
                                      cfg.LowestIncomeAnywhere,
                                      cfg.HighestIncomeAnywhere)
            self.DebtService.GuessBasis = "percent of Income"

        if self.isHomeowner.isGuess:
            self.isHomeowner.Value = "N"
            self.isHomeowner.GuessBasis = "Default is No"

        if self.Cosigner.isGuess:
            if self.isCosigner.isGuess:
                self.isCosigner.Value = "N"
                self.isCosigner.GuessBasis = "Default is No"
            if self.isCosigner.Value == "N":
                self.Cosigner.Value = ""
                self.Cosigner.GuessBasis = "There is no CoSigner"
            else:
                self.Cosigner.Value = strRound(
                                      MyZip.FICO3[self.Zip.Value],
                                      cfg.FicoRound,
                                      cfg.LowestFicoAnywhere,
                                      cfg.HighestFicoAnywhere)
                self.Cosigner.GuessBasis = "from Zip-based model"
        else:
                self.isCosigner.isGuess = False
                self.isCosigner.Value = "Y"
                self.isCosigner.GuessBasis = "An ACTUAL CoSigner Fico exists"

        if self.TradeInValue.isGuess and self.TradeInPayoff.isGuess:
            if self.isTradeIn.isGuess:
                self.isTradeIn.Value = "N"
                self.isTradeIn.GuessBasis = "Default is No"
        else:
            self.isTradeIn.isGuess = False
            self.isTradeIn.Value = "Y"
            self.isTradeIn.GuessBasis = "An ACTUAL Trade-In Value or Payoff exists"

        if self.TradeInValue.isGuess:
            if self.isTradeIn.Value == "N":
                self.TradeInValue.Value = ""
                self.TradeInValue.GuessBasis = "There is no Trade-In"
            else:
                self.TradeInValue.Value = strRound(
                                    float(self.Income.Value) *
                                    cfg.TradeInIncomeMonths,
                                    cfg.TradeInRound,
                                    cfg.LowestTradeInAnywhere,
                                    cfg.HighestTradeInAnywhere)
                self.TradeInValue.GuessBasis = "Months of Income"

        if self.TradeInPayoff.isGuess:
            if self.isTradeIn.Value == "N":
                self.TradeInPayoff.Value = ""
                self.TradeInPayoff.GuessBasis = "There is no Trade-In"
            else:
                self.TradeInPayoff.Value = "0"
                self.TradeInPayoff.GuessBasis = "Set to $0, will be updated"

        if self.UpfrontWant.isGuess:
            if self.UpfrontMax.isGuess:
                self.UpfrontWant.Value = strRound(
                                          max(cfg.LowestUpfrontWanted,
                                          min(cfg.HighestUpfrontWanted,
                                          float(self.Income.Value) *
                                          cfg.UpfrontWantedIncomeMonths)),
                                          cfg.UpfrontRound,
                                          cfg.LowestUpfrontAnywhere,
                                          cfg.HighestUpfrontAnywhere)
                self.UpfrontWant.GuessBasis = "Months of Income"
            else:
                self.UpfrontWant.Value = self.UpfrontMax.Value
                self.UpfrontWant.GuessBasis = "ACTUAL Upfront Maximum"

        if self.UpfrontMax.isGuess:
            if self.UpfrontWant.isGuess:
                self.UpfrontMax.Value = strRound(
                                          max(cfg.LowestUpfrontMax,
                                          min(cfg.HighestUpfrontMax,
                                          float(self.Income.Value) *
                                          cfg.UpfrontMaxIncomeMonths)),
                                          cfg.UpfrontRound,
                                          cfg.LowestUpfrontAnywhere,
                                          cfg.HighestUpfrontAnywhere)
                self.UpfrontMax.GuessBasis = "Months of Income"
            else:
                self.UpfrontMax.Value = self.UpfrontWant.Value
                self.UpfrontMax.GuessBasis = "ACTUAL Upfront Wanted"
        elif float(self.UpfrontMax.Value) < float(self.UpfrontWant.Value):
            self.UpfrontMax.Value = self.UpfrontWant.Value
            self.UpfrontMax.isGuess = True
            self.UpfrontMax.GuessBasis = "OVER-WRITE Max to Equal Wanted"

        if self.MonthlyWant.isGuess:
            if self.MonthlyMax.isGuess:
                self.MonthlyWant.Value = strRound(
                                          max(cfg.LowestMonthlyWanted,
                                          min(cfg.HighestMonthlyWanted,
                                          (float(self.Income.Value) -
                                          float(self.DebtService.Value))*
                                          cfg.MonthlyWantedPercentofIncome)),
                                          cfg.MonthlyRound,
                                          cfg.LowestMonthlyAnywhere,
                                          cfg.HighestMonthlyAnywhere)
                self.MonthlyWant.GuessBasis = "Percent of Income"
            else:
                self.MonthlyWant.Value = self.MonthlyMax.Value
                self.MonthlyWant.GuessBasis = "ACTUAL Monthly Maximum"

        if self.MonthlyMax.isGuess:
            if self.MonthlyWant.isGuess:
                self.MonthlyMax.Value = strRound(
                                          max(cfg.LowestMonthlyMax,
                                          min(cfg.HighestMonthlyMax,
                                          (float(self.Income.Value) -
                                          float(self.DebtService.Value))*
                                          cfg.MonthlyMaxPercentofIncome)),
                                          cfg.MonthlyRound,
                                          cfg.LowestMonthlyAnywhere,
                                          cfg.HighestMonthlyAnywhere)
                self.MonthlyMax.GuessBasis = "Percent of Income"
            else:
                self.MonthlyMax.Value = self.MonthlyWant.Value
                self.MonthlyMax.GuessBasis = "ACTUAL Monthly Wanted"

        elif float(self.MonthlyMax.Value) < float(self.MonthlyWant.Value):
            self.MonthlyMax.Value = self.MonthlyWant.Value
            self.MonthlyMax.isGuess = True
            self.MonthlyMax.GuessBasis = "OVER-WRITE Max to Equal Wanted"

        if self.TermWant.isGuess:
            self.TermWant.Value = cfg.TermWanted
            self.TermWant.GuessBasis = "Always defaults to 72"


#MyConsumer = ConsumerInfo("")
#MyConsumer0 = ConsumerInfo("")