MIME-Version: 1.0 Content-Location: file:///C:/F48430D7/Week7.htm Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset="us-ascii" Week 7

Week = 7

Loops and Booleans Expressions

Indiana University

Computer Science A202 / A598

and Informatics I211

 

This week’s success strategy

<= ![if !supportLists]>n&nb= sp;  The most consistent result of research on learning is this: Learning happen when you are solving problems.

<= ![if !supportLists]>n   Passive learning, such as listening to a lecture or reading a book with few thought= s of your own, is of little value other than as preparation for active learni= ng. Your brain quickly flushes most information unless it is used right away to solve problems.

<= ![if !supportLists]>n&nb= sp;  Active learning means giving assignments and class exercises your best effort.

<= ![if !supportLists]>n   It also means doing your text's (or another text's) self-review questions, exercises, and programming projects (or projects of your own if you prefer) until you can apply the material you have learned.

This = week

<= ![if !supportLists]>n   While loops

<= ![if !supportLists]>n   Iteration patterns

<= ![if !supportLists]>n   Boolean expressions

For l= oops

<= ![if !supportLists]>n   Statement syntax:
for <variable> in <sequence or file expression> <= b>:       <bod= y>

<= ![if !supportLists]>q   <= /span>Semantics: bind <variable> in succession to = each element of the sequence, or line in the file, executing <body> once f= or each binding

<= ![if !supportLists]>n   File iteration possibility is new: does not involve reading entire file into mem= ory as when iterating over a file.readlines() sequence=

<= ![if !supportLists]>n   The sequence may be a range, in which case it is an example of a counted loop

While loops

<= ![if !supportLists]>n   Statement syntax:
while <test expression> :
        =
<body>

<= ![if !supportLists]>q   <= /span>Semantics: repeatedly execute <body> until <test expression> returns a false value, or the loop exits with a bre= ak or an exception

<= ![if !supportLists]>n   Use for loops when the loop is definite, that is, when the number= of iterations is known when the loop starts

<= ![if !supportLists]>n   Use while loops when the loop is not definite

Direct exits from a loop body

<= ![if !supportLists]>n   Statement syntax: break

<= ![if !supportLists]>q   <= /span>semantics: exit from the immediately enclosing for= or while loop

<= ![if !supportLists]>q   <= /span>examples soon

<= ![if !supportLists]>n&nb= sp;  Statement syntax: continue=

<= ![if !supportLists]>q   <= /span>semantics: immediately exit the body of the immediately enclosing for or while loop and continue with the loop's test expression

<= ![if !supportLists]>q   <= /span>rarely used

 =

Loop patterns: counted and accumulator loops

<= ![if !supportLists]>n   Counted loop

<= ![if !supportLists]>q   <= /span>one or more integer variables change value systematically with each loop iteration

<= ![if !supportLists]>q   <= /span>example: any for loop iterating over a range list

<= ![if !supportLists]>n   Accumulator loop

<= ![if !supportLists]>q   <= /span>one or more variables store the result of accumula= ting (gathering) information in the loop

<= ![if !supportLists]>q   example: find the small= est power of 2 that is not of type int

>>> n =3D 1

>>> while type(n) =3D=3D int:

         n =3D n * 2<= o:p>

  

>>> print n<= /o:p>

2147483648

 =

Loop patterns: infinite, interactive, and sentinel loops

<= ![if !supportLists]>n   Infinite loop: a loop that never exits, or exits only when an exceptional condition occurs

<= ![if !supportLists]>q   <= /span>while True: <b= ody>

<= ![if !supportLists]>q   <= /span>appropriate for loops implementing a service that continues until terminated at an unspecified time

<= ![if !supportLists]>q   <= /span>a common kind of while-loop bug in which the test expression remains true

<= ![if !supportLists]>n   Interactive loop

<= ![if !supportLists]>q   <= /span>read interactive input with each iteration

<= ![if !supportLists]>n   Sentinel loop

<= ![if !supportLists]>q   <= /span>a loop that terminates when a specified sentinel v= alue is encountered

Example: an infin= ite accumulator interactive sentinel loop !

=  

def inputNumbers():
 '''Interactively enter a list= of numbers and return
 them in a list.''' # this is a __doc__ comment

    lst =3D [= ]

    print 'Ju= st press <Enter> if there are no more values.'

    while Tru= e:

        value =3D raw_input('Value: ')

        if value =3D=3D '':

        =     break

        lst.append(int(value))

    return ls= t

 =

Loop pattern: post-test loop

<= ![if !supportLists]>n   In a post-test loop, test expression is not evaluated until the body has executed once

<= ![if !supportLists]>n   Commonly used in validation loops that repeatedly input until the input is valid

<= ![if !supportLists]>n   Pattern

while True:
<body>
if <break test expression>: break

<= ![if !supportLists]>n   Example: post-test (potentially) infinite validation loop

while True:
  value =3D input("Enter a positive number: ")
  if value > 0: break<= /o:p>

Loop patterns: file loop and loop-and-a-half

<= ![if !supportLists]>n    File loop

<= ![if !supportLists]>q   <= /span>loop reading lines or characters until the end of a file is reached<= o:p>

<= ![if !supportLists]>q   <= /span>End Of File (EOF) is indicated in Python by reading an empty string

<= ![if !supportLists]>n    In a loop-and-a-half the exit condition is tested somewhere in the middle of the loop

<= ![if !supportLists]>n    Commonly used in sentinel loops with read before a= nd rest of body after testing for the sentenal

<= ![if !supportLists]>n    Pattern

while True:
<body before test>
if <break test expression>: break
<body after test>

<= ![if !supportLists]>n    Example: loop-and-a-half file loop

while True:
 line =3D infile.readline()
 if line =3D=3D '': break # en= d of file
 outfile.write(line)

Boole= an expressions

<= ![if !supportLists]>n   The boolean operators and, or, and not take truth values and retu= rn boolean values

<= ![if !supportLists]>q   <= /span>they actually will take values of any type and interpret them as truth values as usual in Python

<= ![if !supportLists]>n   Precedence of the boolean operators

<= ![if !supportLists]>q   <= /span>not has l= ower precedence than all the non-boolean operators

<= ![if !supportLists]>q   and has lower precedence than not

<= ![if !supportLists]>q   or has lower precedence than and

<= ![if !supportLists]>q   example:
not x =3D=3D 2 and x < 4 or x > 6 is the same as
( not ( x =3D=3D 2 ) and ( x < 4 ) ) or ( x > 6 )

<= ![if !supportLists]>n   Both and and or associate to the left

<= ![if !supportLists]>q   <= /span>example: a and b and c is the same as (a= and b) and c

Boole= an operator semantics

<= ![if !supportLists]>n   not a is True if is false and False= if a is true

<= ![if !supportLists]>n   a and b is true if a and b = are both true and false otherwise

<= ![if !supportLists]>q   <= /span>in Python it is a if a is a f= alse value and b otherwise

<= ![if !supportLists]>n   a or b is true if a is true or b is true and false otherwise

<= ![if !supportLists]>q   <= /span>this is often called and/or in English usage<= /o:p>

<= ![if !supportLists]>q   <= /span>"one or the other, but not both" is call= ed exclusive-or (xor) in computer science

<= ![if !supportLists]>q   <= /span>in Python it is a if a is true and b otherwise

<= ![if !supportLists]>q   a <= span style=3D'font-size:10.0pt;font-family:Arial;mso-bidi-font-family:Arial; mso-bidi-language:#AC45'>!=3D b = can be used to express "a xor b&quo= t; if both a and b are boolean values<= /span>

Boole= an operator semantics, continued

<= ![if !supportLists]>n   and and or are both shortcut (or lazy= ) operators

<= ![if !supportLists]>q   <= /span>their left argument is evaluated first and the rig= ht argument is evaluated only if necessary

<= ![if !supportLists]>q   if a is true, a or b returns True without evaluating b<= /p>

<= ![if !supportLists]>q   if a is false, <= b>a and b returns False without evaluating b

<= ![if !supportLists]>n   Examples

<= ![if !supportLists]>q   len(s) !=3D 0 and= s[0] < 0

<= ![if !supportLists]>n     s[0] <= span style=3D'font-size:9.0pt;font-family:Arial;mso-bidi-font-family:Arial;mso-b= idi-language: #AC45'>would result in an error if len(s) =3D=3D 0=

<= ![if !supportLists]>q   <= /span>x =3D y or 10 is t= he same as

<= ![if !supportLists]>n     if y: x =3D y
else: x =3D 10

 =

Simpl= ifying boolean expressions

<= ![if !supportLists]>n    Double negations cancel each other

<= ![if !supportLists]>q   a =3D=3D not (not= a)

<= ![if !supportLists]>q   <= /span>similar to x =3D - (- x)

<= ![if !supportLists]>n    and and = or distribute over each other

<= ![if !supportLists]>q   a or (b and c) = =3D=3D (a or b) and (a or c)

<= ![if !supportLists]>q   a and (b or c) = =3D=3D (a and b) or (a and c)

<= ![if !supportLists]>n   &nb= sp; similar to x * (y + z) =3D (x * y) + (x * z)

<= ![if !supportLists]>n   &nb= sp; multiplication distributes over addition, but not visa versa

<= ![if !supportLists]>n    DeMorgan's laws

<= ![if !supportLists]>q   not (a or b) =3D= =3D (not a) and (not b)

<= ![if !supportLists]>q   <= /span>not (a and b) =3D=3D (not a) or (not b)

<= ![if !supportLists]>q   <= /span>when negation distributes over and and or, they exchan= ge roles in the process

<= ![if !supportLists]>n    The above equations hold for all values of a, b, and c

<= ![if !supportLists]>n    The simpler form is on the left-hand side

<= ![if !supportLists]>n    It is almost always better style to simplify boole= an expressions when possible

Simpl= ifying predicates

<= ![if !supportLists]>n   Simplify if-else statements with blocks that just return boolean values by using log= ical operators

<= ![if !supportLists]>q   <= /span>especially when you are not very familiar with log= ical operators, it may help sometimes to develop programs using the if-else statements, but for better style simplify them before you are done

<= ![if !supportLists]>q   example:

  if a < b:
    if b < c:
        return True
    else:
        return False
else:
    return False

is the same as the much simpler statement

return a < b and b < c
    =

Predi= cate simplification exercise

<= ![if !supportLists]>n    Simplify:

def isSequence(x):

    if type(x= ) =3D=3D tuple:

        return True

    elif type= (x) =3D=3D list:

        return True

    elif type= (x) =3D=3D str:

        return True

    else: # n= ot a sequence

        return False

<= ![if !supportLists]>n    Answer:

def isSequence(x):

    t =3D typ= e(x)

    return t = =3D=3D tuple or t =3D=3D list or t =3D=3D str

<= ![if !supportLists]>n    There is an even simpler way:

def isSequence(x):

    return ty= pe(x) in (tuple, list, str)

Anoth= er predicate simplification exercise

<= ![if !supportLists]>n   Simplify:

def inUnitRange(x):

    if x >= =3D 0:

        if x > 1:

        =     return False

        else:

        =     return True

    else: # x= is negative

        return False

<= ![if !supportLists]>n   Answer:

def inUnitRange(x):

    return x = >=3D 0 and x <=3D 1

<= ![if !supportLists]>n   Even simpler:

         return 0 <= =3D x <=3D 1

 =

Simpl= ifying relational operation expressions

<= ![if !supportLists]>n   In Python relational operations may be chained as in mathematics

<= ![if !supportLists]>q   example: a < b &l= t; c is the same as a < b and b < c

<= ![if !supportLists]>n   &nb= sp; this is not the same as (a < b) < c, since parenthesis break chains

<= ![if !supportLists]>q   <= /span>this does not work in Java and most other programming languages, forcing you to use more boolean operators=

<= ![if !supportLists]>n   Relational expressions can often be simplified by negating the relational operators; f= or example

<= ![if !supportLists]>q   a !=3D b is the same as not a =3D=3D b

<= ![if !supportLists]>q   a > b <= /b>is the same as not a <=3D b

<= ![if !supportLists]>q   a !=3D b and a &g= t;=3D c is the same as not (a =3D=3D b or a < c)

<= ![if !supportLists]>n   &nb= sp; since not (a =3D=3D b or a < c)

<= ![if !supportLists]>n   &nb= sp; is not (a =3D=3D b) and not (a < c) by DeMorgan's law=

<= ![if !supportLists]>n   &nb= sp; is a !=3D b and a >=3D c by negating both operators=

Boole= an exercise      = ;   s

<= ![if !supportLists]>n&nb= sp;  Simplify: cool and rainy or cool and icy<= o:p>

<= ![if !supportLists]>n&nb= sp;  Answer: cool and (rainy or icy)

<= ![if !supportLists]>q   since and has hi= gher precedence than or and distributes over or<= /p>

<= ![if !supportLists]>n&nb= sp;  Simplify: (x < 3 or y >=3D 5) and (= x < 3 or x =3D=3D 6)

<= ![if !supportLists]>n&nb= sp;  Answer: x < 3 or y >=3D 5 and x =3D= =3D 6

<= ![if !supportLists]>q   <= /span>since or distributes over and and has higher precedence

<= ![if !supportLists]>n&nb= sp;  Simplify: not (x <=3D 3) and not (x = =3D=3D 5)

<= ![if !supportLists]>n&nb= sp;  Answer: x > 3 and x !=3D 5<= /b>

<= ![if !supportLists]>q   <= /span>by negating the operators and canceling double negations

<= ![if !supportLists]>n   What is a simple way to convert a truth value v to its corresponding bool= ean value?

<= ![if !supportLists]>n   Answer: not not v

Boole= an exercise, DeMorgan's law

<= ![if !supportLists]>n&nb= sp;  Simplify: not (x <=3D 3 and not x =3D= =3D 0)

<= ![if !supportLists]>q   <= /span>hint: use DeMorgan's law

<= ![if !supportLists]>n&nb= sp;  Answer: x > 3 or x =3D=3D 0=

<= ![if !supportLists]>q   since not (x <=3D= 3 and not x =3D=3D 0)

<= ![if !supportLists]>q   <= /span>is not (x <=3D 3) or not (not x =3D=3D 0) by DeMorgan's law

<= ![if !supportLists]>q   <= /span>is x > 3 or x =3D=3D 0 by negating opera= tor and double-negation

<= ![if !supportLists]>n   Numerical ranges can also often be visualized and simplified by shading areas on a li= ne (if there is one variable) or a plane (two variables)

<= ![if !supportLists]>q   <= /span>for example, the answer above can be pictured as …..[0]….3[….

Exerc= ise: leap years

<= ![if !supportLists]>n    We can generalize our daysInMonth to account for leap years

def daysInMonth(month, year):

    if month = in [9, 4, 6, 11]:

        return 30

    elif mont= h =3D 2:

        return 28 + leapYear(year)
else:

        return 31

<= ![if !supportLists]>n    Define the function leapYear that takes the year and 1 if it is a leap year and zero otherwise.

<= ![if !supportLists]>q   <= /span>years divisible (evenly: with no remainder) by four are leap years

<= ![if !supportLists]>q   <= /span>unless they are also divisible by 100

<= ![if !supportLists]>q   except years divisible = by 400 are leap years

Leap = year exercise answer

 

def leapYear(year):

    '''Return= 1 if year is a leap year and 0 otherwise.

    Years div= isible (evenly: with no remainder) by four
  are leap years, unless they = are divisible by 100,

    except ye= ars divisible by 400 are leap years.'''

    if (year = % 4 =3D=3D 0
      and = (year % 100 !=3D 0
        =    or year % 400 =3D=3D 0)):

        return 1

    else:

        return 0