WEEK02: numbers and strings
---------------------------------------------------------------
 W: more accumulator review; print formatting; indexing lists and strings

* here's our grade_ave.py program from last time:

"""
show use of for loop...sum a list of numbers

J. Knerr
Spring 2013
"""

#####################################################################

def main():
  """ read in grades, output average grade """

  ngrades = int(raw_input("\nplease enter # of grades: "))
  print ""
 
  total = 0
  for i in range(1,ngrades+1):
    prompt = "grade " + str(i) + ": "
    grade = float(raw_input(prompt))
    total = total + grade
  
  ave = total / float(ngrades)
  
  print "\n\nthe sum of those grades is: %6.2f" % (total)
  print "the ave of those grades is: %6.2f" % (ave)

#####################################################################

main()

 - I used an accumulator to sum the grades entered by the user
 - I also used a for loop and reassigned grade each time through the loop
 - Here's what it would look like without the loop, assuming the user
   enters 5 grades:

ngrades = 5
total = 0
i = 1
prompt = "grade 1: "
grade = float(raw_input(..))
total = total + grade
i = 2
prompt = "grade 2: "
grade = float(raw_input(..))
total = total + grade
i = 3
prompt = "grade 3: "
grade = float(raw_input(..))
total = total + grade
...and so on...

----------------------------------------------------------------------

PRINT FORMATTING: best way to print -- full control over spacing, number of digits, etc

Example: basketball statistics

$ python bball.py 

 Vladimir Radmanovic averaged  0.0 points/game in  2 games
        Lou Williams averaged 11.5 points/game in 13 games
        Lebron James averaged 30.3 points/game in 23 games
        Kevin Durant averaged 28.5 points/game in 20 games
         Kobe Bryant averaged 30.0 points/game in 12 games
       Kevin Garnett averaged 19.2 points/game in 20 games

Everything lines up, no matter how long the names are!


- use these tags in your strings as placeholders for variables:

         %d  for integers   (can also use %i in python)
         %f  for floats
         %s  for strings

- for example:

>>> name = "Ryan Howard"
>>> hrs = 10
>>> ave = 0.290
>>> 
>>> print "%s has hit %d home runs and is batting %f" % (name,hrs,ave)
Ryan Howard has hit 10 home runs and is batting 0.290000

- use %20s to force a 20-character field width:

>>> print "%20s has hit %d home runs and is batting %f" % (name,hrs,ave)
         Ryan Howard has hit 10 home runs and is batting 0.290000

- use %.3f to force only 3 digits after the decimal:

>>> print "%s has hit %d home runs and is batting %.3f" % (name,hrs,ave)
Ryan Howard has hit 10 home runs and is batting 0.290

----------------------------------------------------------------------

INDEXING: how to access individual items from a sequence (list, string)

NOTE: you can accumulate strings and lists, just like numbers
(there's a better way to add to a list, which we'll see in a few weeks)

>>> L = []
>>> for i in range(5):
...   grade = float(raw_input("grade: "))
...   L = L + [grade]
... 
grade: 100
grade: 98.4
grade: 56
grade: 87
grade: 72
>>> print L
[100.0, 98.4, 56.0, 87.0, 72.0]

Once we have the grades stored in a list, how do we access them??

Use square-brackets and indexing:

>>> print L[1]
98.4
>>> print L[0]
100.0
>>>
>>> for i in range(5):
...   print L[i]
... 
100.0
98.4
56.0
87.0
72.0

Can do same for strings:

>>> S = ""
>>> for i in range(5):
...   letter = raw_input("letter: ")
...   S = S + letter
... 
letter: h
letter: e
letter: l
letter: l
letter: o
>>> print S
hello
>>> print S[0]
h
>>> print S[1]
e
>>> for i in range(5):
...   print S[i]
... 
h
e
l
l
o

LISTS are MUTABLE (you can change items in a list)
STRINGS are IMMUTABLE (you can't change characters in a string)

>>> L[2]
56.0
>>> L[2] = L[2] + 20
>>> L[2]
76.0
>>> 
>>> S[0]
'h'
>>> S[0] = "H"
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'str' object does not support item assignment