Decisions, decisions, decisions Chapter 3 Spring 2007 CS 101

advertisement
Decisions, decisions, decisions
Chapter 3
Spring 2007
CS 101
Aaron Bloomfield
1
Background
 Our problem-solving solutions so far have the straight-line
property
 They execute the same statements for every run of the
program
public class DisplayForecast
// main(): application entry point
public static void main(String[] args) {
System.out.print("I think there is a world");
System.out.print(" market for maybe five ");
System.out.println("computers. “);
System.out.print(" Thomas Watson, IBM, “);
System.out.println("1943.“);
}
}
2
Background
 For general problem solving we need more capabilities
 The ability to control which statements are executed
 The ability to control how often a statement is executed
 We will concentrate first on controlling which statements are
executed
 Java provides the if and switch conditional constructs to
control whether a statement list is executed
 The if constructs use logical expressions to determine
their course of action
 We will start with logical expressions
3
Logical expressions
4
Logical expressions
 The branch of mathematics dealing with logical expressions
is Boolean algebra
 Developed by the British mathematician George Boole
5
Logical expressions
 A logical expression has either the value logical true or
logical false
 Some expressions whose values are logical true
 The year 2004 is a leap year
 A meter equals 100 centimeters
 Some expressions whose values are logical false
 A triangle has four sides
 The area of square is always equal to twice its
perimeter
6
Logical expressions
 There are three primary logical operators for manipulating
logical values
 Logical and
 Logical or
 Logical not
 The operators work as most of us would expect
7
Truth tables
 We use truth tables to give formal specifications of the
operators
 “It works as most of us would expect” allows for
ambiguity of interpretation
 Jim is smiling or Patty is smiling
 Can both Jim and Patty both be smiling?
 Truth tables
 Lists all combinations of operand values and the result of
the operation for each combination
p
q
p and q
False
False
True
True
False
True
False
True
False
False
False
True
8
Or and not truth tables
p
q
False
False
True
True
False
True
False
True
p or q
False
True
True
True
p
False
True
not p
True
False
9
Boolean algebra
 Can create complex logical expressions by combining simple
logical expressions
 not (p and q)
p
q
p and q
not (p and q)
False
False
True
True
False
True
False
True
False
False
False
True
True
True
True
False
10
DeMorgan’s laws
 not (p and q) equals (not p) or (not q)
p
False
False
True
True
q
False
True
False
True
p and q
False
False
False
True
(not p) or
not (p and q) ( not p) (not q)
(not q)
True
True
True
False
True
True
True
False
False True
False False
True
True
True
False
11
DeMorgan’s laws
 not (p or q) equals (not p) and (not q)
p
False
False
True
True
q
False
True
False
True
p or q
False
True
True
True
not (p or q)
True
False
False
False
(not p) and
( not p) (not q)
(not q)
True
True
True
False
False True
False False
True
False
False
False
12
DeMorgan’s laws
 If you remember nothing else about the Boolean operators,
remember that:
 not (a and b) == (not a) or (not b)
 not (a or b) == (not a) and (not b)
13
Sidewalk chalk guy

Source:
http://www.gprime.net/images/sidewalkchalkguy/
14
Boolean expressions
15
A boolean type
 Java has the logical type boolean
 Type boolean has two literal constants
 true
 false
 Operators
 The and operator is &&
 Don’t use &
 The or operator is ||
 Don’t use |
 The not operator is !
16
Defining boolean variables

Local boolean variables are uninitialized by default
boolean isWhitespace;
boolean receivedAcknowledgement;
boolean haveFoundMissingLink;
isWhitespace
-
receivedAcknowledgement
-
haveFoundMissingLink
-
17
Defining boolean variables

Local boolean variables with initialization
boolean canProceed = true;
boolean preferCyan = false;
boolean completedSecretMission = true;
canProceed
true
preferCyan
false
completedSecretMission
true
18
Assignment vs. comparison
 = is the assignment operator
 It copies the value on the right to the location on the left
 Consider:
int x;
x = 5;
 The value 5 is copied to the spot x in memory
 == is the comparison operator
 Returns a boolean (true or false) if the two sides are
equal
 Consider:
int x = 5;
System.out.println (x == 5);
System.out.println (x == 6);
19
 Prints out true, false
Other operators
 Equality operators == and !=
 Operator ==
 Returns true if the operands have the same value;
otherwise, returns false
 This is not the assignment operator!
 Operator !=
 Returns true if the operands have different values;
otherwise, returns false
 The operators work with all types of values
20
Evaluating boolean expressions


Suppose
boolean
boolean
boolean
boolean
p = true;
q = false;
r = true;
s = false;
What is the value of
p
!s
q
p && r
q || s
p && s
p == q
q != r
r == s
q != s
21
Evaluating boolean expressions

Suppose
int i = 1;
int j = 2;
int k = 2;
char c = '#';
char d = '%';
char e = '#';

What is the value of
j == k
i == j
c == e
c == d
i != k
j != k
d != e
c != e
22
These images are not animated…
23
Translating English to logical
expressions
25
Translating English to logical expressions


English doesn’t always translate cleanly into logical expressions
To see this, we need to examine the NOR operator
 It doesn’t exist in Java, but we can fake it
 p NOR q == NOT (p OR q)
 NOR is represented by a downward arrow: 
p
False
False
True
True

q
False
True
False
True
p or q
False
True
True
True
not (p or q)
True
False
False
False
In Java, given variables p and q
 NOR is done by: !(p||q)
p nor q
True
False
False
False
26
Translation Example


“I have neither given nor received help on this exam”
 Rephrased: “I have not given nor received …”
 Let p = “I have given help on this exam”
 Let q = “I have received help on this exam”
Translation is: pq
 Remember the precedence: NOT is done first!
p
q
p
pq
T
T
F
F
T
F
F
T
F
T
T
F
F
F
T
F
27
Translation example, take 2


“I have neither given nor received help on this exam”
 Rephrased: “I have not (given nor received …)”
 Let p = “I have given help on this exam”
 Let q = “I have received help on this exam”
Another translation is: (pq) = p || q
p
q
p || q
T
T
T
T
F
T
F
T
T
F
F
F
28
Translation example, rephrased



What is meant is “I have not given and I have not received help
on this exam”
 Or “I have not (given or received) help on this exam”
 This is a DeMorgaization of the one above it
p
q
pq
(p||q)
T
T
F
F
T
F
F
F
F
T
F
F
F
F
T
T
The problem:  has a higher precedence than  in Boolean logic,
but not always in English
Also, “neither” is vague
29
Disclaimer
 The preceding example was showing that when English can
be clear, it does not always translate clearly into Boolean
logic
 The English meaning is exact
 The Boolean translation is not
 This does not mean that you can cheat, and say that I said it
was allowed by the honor code
30
Floating point comparison
31
Floating point precission
 What gets printed?
class FloatTest {
public static void main (String args[]) {
double y = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 +
0.1 + 0.1 + 0.1 + 0.1 + 0.1;
System.out.println (y);
}
}
There are 10 0.1’s
32
Program demo

FloatTest.java
33
Take care with floating-point values
 Consider
double a = 1;
double b = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1
+ 0.1 + 0.1 + 0.1 + 0.1;
double c = .9999999999999999;
 Two true expressions!
c == b
b != a
 Two false expressions!
a == b
b != c
 Problem lies with the finite precision of the floating-point
types
 Instead with the ordering operators for closeness
34
How to solve this
 Don’t compare floating-point values if you can help it!
 Both doubles and floats
 Need to test if the two doubles are “close” in value
final double EPSILON = 0.000001;
boolean foo = Math.abs (a-b) < EPSILON;
35
Sand Castles
36
More on evaluating expressions
37
Ordering operators
 Java provides ordering operators for the primitive types
 Four ordering operators, <, >, <=, and >=
 They correspond to mathematical operators of <, >, ≤,
and ≥
 Together the equality and ordering operators are known as
the relational operators
 False is less than true
38
Evaluation boolean expressions
 Suppose
int i = 1;
int j = 2;
int k = 2;
 What is the value of
i<j
j<k
i <= k
j >= k
i >= k
39
Unicode values
 Character comparisons are based on their Unicode values
 Characters ‘0’, ‘1’, … ‘9’ have expected order
 Character ‘0’ has the encoding 48
 Character ‘1’ has the encoding 49, and so on.
 Upper case Latin letters ‘A’, ‘B’, … ‘Z’ have expected order
 Character ‘A’ has the encoding 65, character ‘B’ has the
encoding 66, and so on.
 Lower case Latin letters ‘a’, ‘b’, … ‘z’ have expected order
 Character ‘a’ has the encoding 97
 Character ‘b’ has the encoding 98, and so on.
40
Evaluation boolean expressions
 Suppose
char c = '2';
char d = '3';
char e = '2';
 What
c
c
c
d
c
is the value of
< d
< e
<= e
>= e
>= e
41
Operator precedence revisited
 Highest to lowest
 Parentheses
 Unary operators
 Multiplicative operators
 Additive operators
 Relational ordering
 Relational equality
 Logical and
 Logical or
 Assignment
42
Expressions vs. statements
 A statement is a single command for Java to do, and always
ends in a semi-colon (for now, at least)
 System.out.println (“hello world”);
 int x = 4;
 ++x;
 An expression returns a value, and does not have a semicolon
 5
 circle.getRadius()
 x
 Note the difference between the following:
 ++i
is an expression
 ++i;
is a statement
43
New 2005 demotivatiors!
44
if statement
45
Conditional constructs
 Provide
 Ability to control whether a statement list is executed
 Two constructs
 If statement
if
if-else
if-else-if
 Switch statement
46
Basic if statement
 Syntax
if (Expression)
Action
 If the Expression is true then
execute Action
 Action is either a single
statement or a group of
statements within braces
Expression
true
false
Action
 For us, it will always be a group
of statements within braces
47
Example
if (value < 0) {
value = -value;
}
Is our number
negative?
If Value is less than
zero then we need
to update its value
to that of its additive
inverse
Value < 0
true
Value = -Value
Our number is now
definitely
nonnegative
false
If Value is not
less than zero
then our number
is fine as is
48
Sorting two values
System.out.print("Enter an integer number: ");
int value1 = stdin.nextInt();
System.out.print("Enter another integer number: ");
int value2 = stdin.nextInt();
// rearrange numbers if necessary
if (value2 < value1) {
// values are not in sorted order
int rememberValue1 = value1;
value1 = value2;
value2 = rememberValue1;
}
// display values
What happens if the
user enters 11 and
28?
What happens if the
user enters 11 and
4?
System.out.println("The numbers in sorted order are "
+ value1 + " and then " + value2);
49
Are the numbers out
of order
If semantics
Rearrange value1 and
value2 to put their
values in the proper
order
value2 < value1
true
false
int rememberValue1 = value1
value1 = value2
value2 = rememberValue1
The numbers were rearranged into
the proper order
The numbers were initially in
order
The numbers are in order
What an if statement executes

An if statement executes the next block of code

A block is either:

A single statement without curly brackets:
if (a == b)
System.out.println (“a==b!!!”);

A number of statements enclosed by curly brackets:
if (a == b) {
System.out.print (“a”);
System.out.print (“==”);
System.out.print (“b”);
System.out.println (“!!!”);
}
51
Why we always use braces
 What is the output?
int m = 5;
int n = 10;
if (m < n)
++m;
++n;
System.out.println(" m = " + m + " n = “ + n);
52
Warn your grandparents!

Historically, this class has been lethal to
grandparents of students in the class
– More often grandmothers

This happens most around test time
– Although occasionally around the times a big
assignment is due

See
http://www.cis.gsu.edu/~dstraub/Courses/Grandma.htm53
if-else statement
54
The if-else statement
 Syntax
if (Expression)
Action1
else
Action2
 If Expression is
execute
Action1
execute Action2
Expression
true then
otherwise
 The actions are either a single
statement
or
a
list
of
statements within braces
true
false
Action1
Action2
55
Finding the maximum of two values
System.out.print("Enter an integer number: ");
int value1 = stdin.nextInt();
System.out.print("Enter another integer number: ");
int value2 = stdin.nextInt();
But is it initialized?
int maximum;
if (value1 < value2) {
// is value2 larger?
maximum = value2;
// yes: value2 is larger
}
else { // (value1 >= value2)
maximum = value1;
// no: value2 is not larger
}
System.out.println("The maximum of " + value1
+ " and " + value2 + " is " + maximum);
56
Finding the maximum of two values
System.out.print("Enter an integer number: ");
int value1 = stdin.nextInt();
System.out.print("Enter another integer number: ");
int value2 = stdin.nextInt();
int maximum;
if (value1 < value2) {
maximum = value2;
}
But is it initialized?
// is value2 larger?
// yes: value2 is larger
System.out.println("The maximum of " + value1
+ " and " + value2 + " is " + maximum);
57
Finding the maximum of two values
Is value2 larger than value1
Yes, it is . So value2 is
larger than value1. In
this case, maximum is
set to value2
value1 < value2
true
maximum = value2
Either case, maximum is set
correctly
No, its not. So value1
is at least as large as
value2. In this case,
maximum is set to
value1
false
maximum = value1
58
Why we use whitespace
 What does the following do?
System.out.print("Enter an integer number: ");
int value1 = stdin.nextInt();
System.out.print("Enter another integer number: ");
int value2 = stdin.nextInt();
if (value2 < value1) {
int rememberValue1 = value1;
value1 = value2;
value2 = rememberValue1;
}
System.out.println("The numbers in sorted order are "
+ value1 + " and then " + value2);
59
How do you like your braces?
if (a == b)
{
//...
}
else {
//...
}
if (a == b) {
//...
}
else {
//...
}
if (a == b)
{
//...
} else
{
//...
}
if (a == b) {
//...
} else {
//...
}
if (a == b)
{
//...
}
else
{
//...
}
61
If-then-else precedence
if (number != 0)
if (number > 0)
System.out.println("positive");
Which if does this
else
else refer to?
System.out.println("negative");
62
If-then-else precedence without
whitespace
if (number != 0)
if (number > 0)
System.out.println("positive");
else
System.out.println("negative");
else
System.out.println("zero");
63
Program demo

ElsePrecedence.java
64
Becoming an IEEE author
65
if-else-if statement
66
If-else-if
 Consider
if (number == 0) {
System.out.println("zero");
}
else {
if (number > 0) {
We can change
the whitespace
of the code
These braces
aren’t needed
System.out.println("positive");
}
}
else {
System.out.println("negative");
}Same results as previous segment – but this segment
better expresses the meaning of what is going on 67
Sorting three values
 For sorting values n1, n2, and n3 there are six possible
orderings
 n1  n2  n3
 n1  n3  n2
 n2  n1  n3
 n2  n3  n1
 n3  n1  n2
 n3  n2  n1
 Suppose s1, s2, s3 are to be a sorted version of n1, n2, and
n3
68
Sorting three values
if ((n1 <= n2) && (n2 <= n3))
s1 = n1;
s2 = n2;
s3 =
}
else if ((n1 <= n3) && (n3 <=
s1 = n1;
s2 = n3;
s3 =
}
else if ((n2 <= n1) && (n1 <=
s1 = n2;
s2 = n1;
s3 =
}
else if ((n2 <= n3) && (n3 <=
s1 = n2;
s2 = n3;
s3 =
}
else if ((n3 <= n1) && (n1 <=
s1 = n3;
s2 = n1;
s3 =
}
else { // n3 <= n2 <= n1
s1 = n3;
s2 = n2;
s3 =
}
{
n3;
// n1 <= n2 <= n3
n2)) { // n1 <= n3 <= n2
n2;
n3)) { // n2 <= n1 <= n3
n3;
n1)) { // n2 <= n3 <= n1
n1;
n2)) { // n3 <= n1 <= n2
n2;
n1;
69
?: notation
70
Finding the minimum value
 Consider:
// z is to hold the minimum of x and y
if ( x < y )
z = x;
Notice no braces!
else
z = y;
 Another way to do this:
z = (x<y) ? x : y;
71
The ?: notation

Only works when both “cases” return a value!
 Meaning when both “cases” are expressions
 Example: z = (x<y) ? x : y;
 Thus, you can’t put a print statement in there!

Can be difficult to read
System.out.println ((number != 0) ? ((number > 0) ? "positive“ :
"negative") : "zero“);
if (number != 0)
if (number > 0)
System.out.println("positive");
else
System.out.println("negative");
else
System.out.println("zero");
72
A bit of humor…
73
switch statement
74
Switch statement
 Software engineers often confronted with programming tasks
where required action depends on the values of integer
expressions
 The if-else-if construct can be used
 Separately compare the desired expression to a
particular value
 If the expression and value are equal, then perform
the appropriate action
 Because such programming tasks occur frequently
 Java includes a switch statement
 The task is often more readable with the switch then
with the if-else-if
75
A switch statement example
if (a == ‘0’)
System.out.println
else if (a == ‘1’)
System.out.println
else if (a == ‘2’)
System.out.println
else if (a == ‘3’)
System.out.println
else if (a == ‘4’)
System.out.println
else
System.out.println
(“zero”);
(“one”);
(“two”);
(“three”);
(“four”);
(“five+”);
switch (a) {
case ‘0’:
System.out.println
break;
case ‘1’:
System.out.println
break;
case ‘2’:
System.out.println
break;
case ‘3’:
System.out.println
break;
case ‘4’:
System.out.println
break;
default:
System.out.println
break;
(“zero”);
(“one”);
(“two”);
(“three”);
(“four”);
(“five+”);
76
Switch statement
Integral expression to
be matched with a case
expression
switch ( SwitchExpression )
case CaseExpression1 :
Action1 ;
case CaseExpression2 :
Action2 ;
Java
statements
{
Constant
integral
expression
...
case CaseExpressionn :
Actionn ;
default :
}
Actionn+1 ;
78
Testing for vowel-ness
switch
case
case
case
case
case
case
case
case
case
case
}
(ch) {
'a':
'A':
'e':
'E':
'i':
'I':
'o':
'O':
'u':
'U':
System.out.println("vowel“);
break;
default:
System.out.println("not a vowel“);
79
Testing for vowel-ness
switch (ch) {
case 'a': case 'A':
case 'e': case 'E':
case 'i': case 'I':
case 'o': case 'O':
case 'u': case 'U':
System.out.println("vowel“);
break;
The break causes an exiting of the switch
default:
System.out.println("not a vowel“);
}
Handles all of the other cases
80
A better way to format that switch
statement
switch (ch) {
case 'a':
// FALL
case 'A':
// FALL
case 'e':
// FALL
case 'E':
// FALL
case 'i':
// FALL
case 'I':
// FALL
...
THRU
THRU
THRU
THRU
THRU
THRU
81
Processing a request
System.out.print("Enter a number: ");
int n1 = stdin.nextInt();
System.out.print("Enter another number: ");
int n2 = stdin.nextInt();
System.out.print("Enter desired operator: ");
char operator = stdin.nextLine().charAt(0);
switch (operator) {
case '+' : System.out.println((n1 + n2)); break;
case '-' : System.out.println(n1 - n2); break;
case '*' : System.out.println(n1 * n2); break;
case '/' : System.out.println(n1 / n2); break;
default: System.out.println(“Illegal request“);
}
82
How well do you feel you understand the
swtich statement?
1. Very well!
This stuff is
easy!
2. Fairly well – with a little
review, I’ll be good
3. Okay. It’s not great, but
it’s not horrible, either
4. Not well.
I’m kinda
confused
5. Not at all. I’m soooooo
lost
oo
...
so
oo
c.
..
I’m
ll.
N
ot
at
a
w
el
l.
ot
N
da
ki
n
I’m
no
It’
s
y.
ka
O
,b
u.
..
tg
re
at
a
ith
w
w
el
l–
irl
y
Fa
Ve
ry
w
el
l!
Th
is
st
uf
fi
...
lit
t..
20% 20% 20% 20% 20%
83
Biggest software errors

Ariane 5 rocket explosion (1996)
– Due to loss of precision converting 64-bit double to 16-bit int

Pentium division error (1994)
– Due to incomplete look-up table (like an array)

Patriot-Scud missile error (1991)
– Rounding error on the time
– The missile did not intercept an incoming Scud missile, leaving 28 dead and 98
wounded

Mars Climate Orbiter (1999)
– Onboard used metric units; ground computer used English units

AT&T long distance (1990)
– Wrong break statement in C code

Therac-25, X-ray (1975-1987)
– Badly designed software led to radiation overdose in chemotherapy patients

NE US power blackout (2003)
– Flaw in GE software contributed to it

References: http://www5.in.tum.de/~huckle/bugse.html,
http://en.wikipedia.org/wiki/Computer_bug,
http://www.cs.tau.ac.il/~nachumd/verify/horror.html
84
Object equality
85
Testing variables for equality
 Consider
System.out.print("Enter an integer number: ");
int n1 = stdin.nextInt();
System.out.print("Enter another integer number: ");
int n2 = stdin.nextInt();
if (n1 == n2) {
System.out.println("Same");
}
else {
System.out.println(“Different");
}
What is the output if the user enters 88 and 3?
What is the output if the user enters 88 both times?
86
Program Demo

IntEquality
87
Testing objects for equality
 Consider
String s1 = “pastel”;
String s2 = s1;
if (s1 == s2) {
System.out.println("Same");
}
else {
System.out.println("Different");
}
88
Testing objects for equality
 Memory looks like
s1
"pastel"
s2
 The comparison is between the references!
 Thus, s1 and s2 are the same (they refer to the same
object)
89
Testing objects for equality
 Consider
System.out.print("Enter a string: ");
String s1 = stdin.nextLine();
System.out.print("Enter another string: ");
String s2 = stdin.nextLine();
if (s1 == s2) {
System.out.println("Same");
}
else {
System.out.println("Different");
}
What is the output if the user enters "pastel" both
times?
90
Program Demo

StringEquality
91
Testing objects for equality
 When it is executed
System.out.print("Enter a string: ");
String s1 = stdin.nextLine();
System.out.print("Enter another string: ");
String s2 = stdin.nextLine();
 Memory looks like
s1
"pastel"
s2
"pastel"
 As a result no matter what is entered s1 and s2 are not the
same
92
 They refer to different objects
Comparing strings for equality
 Consider:
String u = new String("hello");
String v = new String("hello");
System.out.println (u == v);
 What gets printed?
These aren’t the
 false
exact same thing
 Consider:
String s = "hello";
String t = "hello";
System.out.println (s == t);
 What gets printed?
 true
 Huh?
93
Program Demo

StringEquality2
94
Testing operators for equality

Consider
System.out.print("Enter a string: ");
String s1 = stdin.nextLine();
System.out.print("Enter another string: ");
String s2 = stdin.nextLine();
Tests whether s1 and s2
represent the same object
if (s1.equals(s2)) {
System.out.println("Same");
}
else {
System.out.println("Different");
}
Most classes have a method equals(). It compares the
objects themselves, not the references.
95
Today’s demotivators
96
Short-circuit evaluation
97
Short-circuit evaluation
 The value of a logical expression can be known before all the
operands have been considered
 If left operand of && is false, then the value must be false
 If left operand of || is true, then the value must be true
 Java uses these properties to make logical operations
efficient
 Evaluates left operand before it evaluates right operand
 If the operator value is determined from the left operand,
then the right operand is not evaluated
 The operation is short-circuited
98
Short-circuit evaluation
 Short-circuit evaluation is useful when some property must
be true for some other expression to be evaluated
 Suppose you are interested in knowing whether scoreSum
divided by nbrScores is greater than value
 The condition can be evaluated only if nbrScores is
nonzero
 The following expression correctly represents the condition
(nbrScores != 0) && ((scoreSum / nbrScores) > value)
99
Short-circuit evaluation
Output
returnsFalse() called
 Assume we have a returnsFalse()
method from a ‘foo’ object
 It returns false
 And it prints “returnsFalse() called”
 And a returnsTrue() method
 Consider:
if
}
if
}
if
}
if
}
returnsTrue() called
returnsFalse() called
returnsFalse() called
returnsTrue() called
returnsTrue() called
( foo.returnsFalse() && foo.returnsTrue() ) {
( foo.returnsTrue() && foo.returnsFalse() ) {
( foo.returnsFalse() || foo.returnsTrue() ) {
( foo.returnsTrue() || foo.returnsFalse() ) {
100
How well do you feel you understand decision
statements (ifs, switches) in Java?
1. Very well!
This stuff is
easy!
2. Fairly well – with a little
review, I’ll be good
3. Okay. It’s not great, but
it’s not horrible, either
4. Not well.
I’m kinda
confused
5. Not at all. I’m soooooo
lost
oo
...
so
oo
c.
..
I’m
ll.
N
ot
at
a
w
el
l.
ot
N
da
ki
n
I’m
no
It’
s
y.
ka
O
,b
u.
..
tg
re
at
a
ith
w
w
el
l–
irl
y
Fa
Ve
ry
w
el
l!
Th
is
st
uf
fi
...
lit
t..
20% 20% 20% 20% 20%
101
Download