Chapter 7 Behavior Control
--------------------------

Previous chapter
  sensor-motor wiring
  reactive behavior

This chapter - more complex behaviors/tasks.

Behavior-based control
----------------------
A different way to structure programs: instead of looking at
sensor values and using them to provide input to motors, focus the
design of programs based on number and type of behavior.

e.g. Corral exiting behavior:
  cruise (in absence of obstacles/light)
  avoid obstacles (if present)
  seek light (if present)

See figure on page 160

3 behaviors:

SeekLight
Avoid
Cruise

Each of these 3 behaviors output a triple:
  Yes/No, Translate Speed, Rotate Speed
Yes: behavior has a recommendation
No: no recommendation (e.g. when no light is detected, no
    recommendation)

Arbitrate module: decides what to do based on recommendations.
We will choose simple arbitration: using priorities
In this example:
  Highest priority - SeekLight
  Middle priority - Avoid
  Lowest priority - Cruise

****************************************************
from myro import *
init("com8")

cruiseSpeed = 0.8
turnSpeed = 0.8
lightThresh = 80

def cruise():
    return [True, cruiseSpeed, 0]

def avoid():
    L, R = getIR()
    L = 1 - L
    R = 1 - R

    if L:
        return [True, 0, -turnSpeed]
    elif R:
        return [True, 0, turnSpeed]
    else:
        return [False, 0, 0]

def seekLight():
    L, C, R = getLight()

    if L < lightThresh:
        return [True, cruiseSpeed/2.0, turnSpeed]
    elif R < lightThresh:
        return [True, cruiseSpeed/2.0, -turnSpeed]
    else:
        return [False, 0, 0]

behaviors = [seekLight, avoid, cruise]

def arbitrate():
    for behavior in behaviors:
        output, T, R = behavior()
        if output:
            return [T, R]

def main():
    setForwardness("scribbler-forward")
    while True:
        T, R = arbitrate()
        move(T, R)

main()
*********************************************************

Names and returns values 
------------------------

Python names used for functions
Lists to store objects (e.g. pictures)
List of function names (objects)!

behaviors = [seekLight, avoid, cruise]
for behavior in behaviors:
  output, L, R = behavior()

Note: There is no function called behavior in the
program! the variable behavior is used to denote
one of the 3 functions that are defined in the program.

Each of the functions returns a list of values.

Python Math library
-------------------
Library of useful pre-built functions are called APIs -
Application Programming Interface

from math inport *

ceil(x) - returns smallest integer greater or equal to x
floor(x) - returns greatest integer less than or equal to x
exp(x) - returns e to the power x
log(x) - returns natural log of x
log10(x) - returns base-10 of log of x
log(x,base) - returns log of x with respect to base
pow(x,y) - returns x to the power y
sqrt(x) - returns square root of x

import math
math.ceil(5.34)
...
This version of import is useful if two functions in different
libraries have the same name!!

Doing Calculations
------------------

Loan Calculator Program:
See formula on Page 168 for Monthly payment

########################################################
# Page 170
from math import *

def main():
    # First, note the cost of the car (Cost),
    Cost = input("Enter the cost of the car: $")

    # the amount of money you have saved (Cash),
    Cash = input("Enter the amount of money you saved: $")

    # and the sales tax rate (TaxRate) (6% e.g.)
    SalesTaxRate = 6.0

    # Also, note the financials: the interest rate (APR),
    # and the term of the loan (Term)
    # The interest rate quoted is generally the annual
    # percentage rate (APR)
    APR = input("Enter the APR for the loan (in %): ")

    # Input the term of the loan (Term)
    term = input("Enter length of loan term (in months): ")

    # Convert it (APR) to monthly rate (divide it by 12) (MR)
    # also divide it by 100 since the value input is in %
    MR = APR/12.0/100.0

    # Next, compute the sales tax you will pay (SalesTax)
    SalesTax = Cost * SalesTaxRate / 100.0

    # Use the money left to make a down payment (DownPayment)
    DownPayment = Cash - SalesTax

    # Then determine the amount you will borrow (LoanAmount)
    LoanAmount = Cost - DownPayment

    # Plug in all of the values in the formula and compute
    # the monthly payment (MP)
    MP = (LoanAmount * MR) / (1.0 - exp(-term * log(1.0+MR)))

    # Also, compute the total cost of the car. (TotalCost)
    TotalCost = SalesTax + DownPayment + MP * term

    # Output all the results
    print "Here are the details about your new car..."
    print "------------------------------------------"
    print
    print "Money you have saved $", Cash
    print "Cost of the car $", Cost
    print "Sales Tax rate is", SalesTaxRate, "%"
    print "Sales Tax on the car $", SalesTax
    print "Your down payment will be $", DownPayment
    print "You will be borrowing $", LoanAmount
    print "A", term, "month loan at", APR, "% APR"
    print "Your monthly payment will be $", MP
    print "Total cost will be $", TotalCost
    print

main()
########################################################

Run above program with following values:

Saved Money = 5500
Cost of car: 20000
Sales Tax: 6%
Term of loan = 36 months
Interest Rate: 6.9% APR

Notice Output: 
  Monthly Payment $484.052914723
  Total Cost = 22925.90493

How do we format these values with 2 decimal points?

Formatting Output
-----------------

String formatting:

String % expression

"Value of PI = %5.3f" % (math.pi) # right justified
"Value of PI = %-5.3f" % (math.pi) # left justified
"Value of PI = %1.3f" % (math.pi) # right justified total spaces = 1!!
"Hello %10s, how are you?" % "Arnold" # right justified
"Hello %-10s, how are you?" % "Arnold"  # left justified
"My age is %3d years" % 25

Output formatted Loan Program
####################################################
# Output all the results
    print "Here are the details about your new car..."
    print "------------------------------------------"
    print
    print "Money you have saved $%1.2f" % Cash
    print "Cost of the car $%1.2f" % Cost
    print "Sales Tax rate is %1.2f%%" % SalesTaxRate
    print "Sales Tax on the car $%1.2f" % SalesTax
    print "Your down payment will be $%1.2f" % DownPayment
    print "You will be borrowing $%1.2f" % LoanAmount
    print "A %2d month loan at %1.2f%% APR" % (term, APR)
    print "Your monthly payment will be $%1.2f" % MP
    print "Total cost will be $%1.2f" % TotalCost
    print
####################################################

Decision Making in Computer Programs
------------------------------------
Any problem is solvable using
  Sequential execution
  decision making (if-elif-else...)
  repetition (for-loop, while-loop)

Rock-Paper-Scissors Game:

Main algorithm:

# Computer makes a selection
# User is asked for his/her selection
# Decide who won or draw
# Inform player of decision

items = ["Paper","Scissors","Rock"]

Computer's selection (my):

x = randint(0,2)
myChoice = items[x]

or 

myChoice = items[randint(0,2)]

Player's selection (your):

yourChoice = askQuestion("Pick an item.",items)

How to decide who won?

if both picked same item then it is a draw
if myChoice beats yourChoice then I win
else You win

if (myChoice == yourChoice):
  print "It is a draw"
if (myChoice == "Paper" and yourChoice == "Rock") or
   (myChoice == "Scissors" and yourChoice == "Paper") or
   (myChoice == "Rock" and yourChoice == "Scissors")
  print "I win"
else:
  print "You win"

Full Program:
includes a function beats(me,you)

################################################
# A program that plays the game of Paper, Scissors, Rock!
from myro import *
from random import randint

def beats(me, you):
    # Does me beat you? If so, return True, False otherwise.
    
    if me == "Paper" and you == "Rock":
        # Paper beats rock
        return True
    elif me == "Scissors" and you == "Paper":
        # Scissors beat paper
        return True
    elif me == "Rock" and you == "Scissors":
        # Rock beats scissors
        return True
    else:
        return False

def main():
    # Play a round of Paper, Scissors, Rock!
    print "Lets play Paper, Scissors, Rock!"
    print "In the window that pops up, make your selection>"
    
    items = ["Paper", "Scissors", "Rock"]
    
    # Computer and Player make their selection...
    # Computer makes a selection
    myChoice = items[randint(0, 2)]

    # Player makes a selection
    yourChoice = askQuestion("Pick an item.", items)
    
    # inform Player of choices
    print
    print "I picked", myChoice
    print "You picked", yourChoice

    # Decide if it is a draw or a win for someone
    if myChoice == yourChoice:
        print "We both picked the same thing."
        print "It is a draw."
    elif beats(myChoice, yourChoice):
        print "Since", myChoice, "beats", yourChoice, "..."
        print "I win."
    else:
        print "Since", yourChoice, "beats", myChoice, "..."
        print "You win."

    print "Thank you for playing. Bye!"

main()
################################################

Modify the program to play several rounds; keep track of
score; at end print the scores.