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
Loops and Booleans Expressions
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
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
Loop
patterns: file loop and loop-and-a-half
<=
![if !supportLists]>n =
span>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 =
span>In a loop-and-a-half the exit condition is tested
somewhere in the middle of the loop
<=
![if !supportLists]>n =
span>Commonly used in sentinel loops with read before a=
nd
rest of body after testing for the sentenal
<=
![if !supportLists]>n =
span>Pattern
while
True:
<body before test>
if <break test expression>: break
<body after test>
<=
![if !supportLists]>n =
span>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
<=
![if !supportLists]>q
or
<=
![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
<=
![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
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
<=
![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 =
span>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 =
span>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 =
span>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 =
span>The simpler form is on the left-hand side
<=
![if !supportLists]>n =
span>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 =
span>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 =
span>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 =
span>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=
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
<=
![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
<=
![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 =
span>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 =
span>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