Ternary operator not working in Android - java

I have a simple question that boggles me. I am trying to use the ternary operator in java. I am new to Android and java. This code gives me the error:
amt < 0 ? lendBtn.setChecked(true) : lendBtn.setChecked(false);
"Syntax error on token "<", invalid AssignmentOperator"
So, I replace it with an if statement and it totally works:
if (amt < 0) { ... }
It's not a big deal but does anyone know why?

This has nothing to do with Android. You can't use a conditional expression as a statement on its own... and the second and third operands can't be void expressions either.
You should use:
lendBtn.setChecked(amt < 0);
... which is simpler to start with.

Related

Why can't you make conditional assignment in short hand IF statement?

I'm trying to update softcount for my Blackjack game to account for Aces being played (value 11 or 1). When using the short-form IF statement, why is the first line of code incorrect, but the second line is okay to use? Is this type of if statement limited?
(counter > 1) ? (softcount+=1) : (softcount+=value); // bad
softcount += (counter > 1) ? 1 : value; // good
It is simply how the language is defined.
Only certain expressions - statement expressions - can be made into a statement by adding ;. (Statement expression + ; is an expression statement).
From JLS Sec 14.8:
ExpressionStatement:
StatementExpression ;
StatementExpression:
Assignment
PreIncrementExpression
PreDecrementExpression
PostIncrementExpression
PostDecrementExpression
MethodInvocation
ClassInstanceCreationExpression
Conditional expressions are not statement expressions.
The ternary has to be seen as a way to evaluate something and not as a way to apply a processing.
So it expects some expressions after ? but you wrote statements : softcount+=1 and (softcount+=value) in the first code.
In the second code, it is ok because you specified two expressions : 1 and value.
Besides do you really find this code a short hand ?
(counter > 1) ? (softcount+=1) : (softcount+=value); // bad
You repeat the increment part.
What you want in your case is just :
if (counter > 1) { softcount+=1;} else {softcount+=value;)
It is called ternary operator, it is used when you simply want to return a value based on condition. It's main purpose is to avoid if else for simple avaluations. In your case you should use if else.

Java - Syntax, what does this mean? [duplicate]

I have been working with Java a couple of years, but up until recently I haven't run across this construct:
int count = isHere ? getHereCount(index) : getAwayCount(index);
This is probably a very simple question, but can someone explain it? How do I read it? I am pretty sure I know how it works.
if isHere is true, getHereCount() is called,
if isHere is false getAwayCount() is called.
Correct? What is this construct called?
Yes, it is a shorthand form of
int count;
if (isHere)
count = getHereCount(index);
else
count = getAwayCount(index);
It's called the conditional operator. Many people (erroneously) call it the ternary operator, because it's the only ternary (three-argument) operator in Java, C, C++, and probably many other languages. But theoretically there could be another ternary operator, whereas there can only be one conditional operator.
The official name is given in the Java Language Specification:
§15.25 Conditional Operator ? :
The conditional operator ? : uses the boolean value of one expression to decide which of two other expressions should be evaluated.
Note that both branches must lead to methods with return values:
It is a compile-time error for either the second or the third operand expression to be an invocation of a void method.
In fact, by the grammar of expression statements (§14.8), it is not permitted for a conditional expression to appear in any context where an invocation of a void method could appear.
So, if doSomething() and doSomethingElse() are void methods, you cannot compress this:
if (someBool)
doSomething();
else
doSomethingElse();
into this:
someBool ? doSomething() : doSomethingElse();
Simple words:
booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse
Others have answered this to reasonable extent, but often with the name "ternary operator".
Being the pedant that I am, I'd like to make it clear that the name of the operator is the conditional operator or "conditional operator ?:". It's a ternary operator (in that it has three operands) and it happens to be the only ternary operator in Java at the moment.
However, the spec is pretty clear that its name is the conditional operator or "conditional operator ?:" to be absolutely unambiguous. I think it's clearer to call it by that name, as it indicates the behaviour of the operator to some extent (evaluating a condition) rather than just how many operands it has.
According to the Sun Java Specification, it's called the Conditional Operator. See section 15.25. You're right as to what it does.
The conditional operator ? : uses the boolean value of one expression to decide which of two other expressions should be evaluated.
The conditional operator is syntactically right-associative (it groups right-to-left), so that a?b:c?d:e?f:g means the same as a?b:(c?d:(e?f:g)).
ConditionalExpression:
ConditionalOrExpression
ConditionalOrExpression ? Expression : ConditionalExpression
The conditional operator has three operand expressions; ? appears between the first and second expressions, and : appears between the second and third expressions.
The first expression must be of type boolean or Boolean, or a compile-time error occurs.
condition ? truth : false;
If the condition is true then evaluate the first expression. If the condition is false, evaluate the second expression.
It is called the Conditional Operator and it is a type of Ternary Operation.
int count = isHere ? getHereCount(index) : getAwayCount(index);
means :
if (isHere) {
count = getHereCount(index);
} else {
count = getAwayCount(index);
}
Not exactly correct, to be precise:
if isHere is true, the result of getHereCount() is returned
otheriwse the result of getAwayCount() is returned
That "returned" is very important. It means the methods must return a value and that value must be assigned somewhere.
Also, it's not exactly syntactically equivalent to the if-else version. For example:
String str1,str2,str3,str4;
boolean check;
//...
return str1 + (check ? str2 : str3) + str4;
If coded with if-else will always result in more bytecode.
Ternary, conditional; tomato, tomatoh. What it's really valuable for is variable initialization. If (like me) you're fond of initializing variables where they are defined, the conditional ternary operator (for it is both) permits you to do that in cases where there is conditionality about its value. Particularly notable in final fields, but useful elsewhere, too.
e.g.:
public class Foo {
final double value;
public Foo(boolean positive, double value) {
this.value = positive ? value : -value;
}
}
Without that operator - by whatever name - you would have to make the field non-final or write a function simply to initialize it. Actually, that's not right - it can still be initialized using if/else, at least in Java. But I find this cleaner.
You might be interested in a proposal for some new operators that are similar to the conditional operator. The null-safe operators will enable code like this:
String s = mayBeNull?.toString() ?: "null";
It would be especially convenient where auto-unboxing takes place.
Integer ival = ...; // may be null
int i = ival ?: -1; // no NPE from unboxing
It has been selected for further consideration under JDK 7's "Project Coin."
This construct is called Ternary Operator in Computer Science and Programing techniques. And Wikipedia suggest the following explanation:
In computer science, a ternary operator (sometimes incorrectly called a tertiary operator) is an operator that takes three arguments. The arguments and result can be of different types. Many programming languages that use C-like syntax feature a ternary operator, ?: , which defines a conditional expression.
Not only in Java, this syntax is available within PHP, Objective-C too.
In the following link it gives the following explanation, which is quiet good to understand it:
A ternary operator is some operation operating on 3 inputs. It's a shortcut for an if-else statement, and is also known as a conditional operator.
In Perl/PHP it works as: boolean_condition ? true_value : false_value
In C/C++ it works as: logical expression ? action for true : action for false
This might be readable for some logical conditions which are not too complex otherwise it is better to use If-Else block with intended combination of conditional logic.
We can simplify the If-Else blocks with this Ternary operator for one code statement line.For Example:
if ( car.isStarted() ) {
car.goForward();
} else {
car.startTheEngine();
}
Might be equal to the following:
( car.isStarted() ) ? car.goForward() : car.startTheEngine();
So if we refer to your statement:
int count = isHere ? getHereCount(index) : getAwayCount(index);
It is actually the 100% equivalent of the following If-Else block:
int count;
if (isHere) {
count = getHereCount(index);
} else {
count = getAwayCount(index);
}
That's it!
Hope this was helpful to somebody!
Cheers!
Correct. It's called the ternary operator. Some also call it the conditional operator.
Its Ternary Operator(?:)
The ternary operator is an operator that takes three arguments. The first
argument is a comparison argument, the second is the result upon a true
comparison, and the third is the result upon a false comparison.
Actually it can take more than 3 arguments. For instance if we want to check wether a number is positive, negative or zero we can do this:
String m= num > 0 ? "is a POSITIVE NUMBER.": num < 0 ?"is a NEGATIVE NUMBER." :"IT's ZERO.";
which is better than using if, else if, else.
?: is a Ternary Java Operator.
Its syntax is:
condition ? expression1 : expression2;
Here, the condition is evaluated and
condition returns true, the expression1 will execute.
condition returns false, the expression2 will execute.
public class Sonycode {
public static void main(String[] args) {
double marks = 90;
String result = (marks > 40) ? "passed in exam" : "failed in exam";
System.out.println("Your result is : " + result);
}
}
Output :-
Your result is : passed in exam
It's the conditional operator, and it's more than just a concise way of writing if statements.
Since it is an expression that returns a value it can be used as part of other expressions.
Yes, you are correct. ?: is typically called the "ternary conditional operator", often referred to as simply "ternary operator". It is a shorthand version of the standard if/else conditional.
Ternary Conditional Operator
I happen to really like this operator, but the reader should be taken into consideration.
You always have to balance code compactness with the time spent reading it, and in that it has some pretty severe flaws.
First of all, there is the Original Asker's case. He just spent an hour posting about it and reading the responses. How longer would it have taken the author to write every ?: as an if/then throughout the course of his entire life. Not an hour to be sure.
Secondly, in C-like languages, you get in the habit of simply knowing that conditionals are the first thing in the line. I noticed this when I was using Ruby and came across lines like:
callMethodWhatever(Long + Expression + with + syntax) if conditional
If I was a long time Ruby user I probably wouldn't have had a problem with this line, but coming from C, when you see "callMethodWhatever" as the first thing in the line, you expect it to be executed. The ?: is less cryptic, but still unusual enough as to throw a reader off.
The advantage, however, is a really cool feeling in your tummy when you can write a 3-line if statement in the space of 1 of the lines. Can't deny that :) But honestly, not necessarily more readable by 90% of the people out there simply because of its' rarity.
When it is truly an assignment based on a Boolean and values I don't have a problem with it, but it can easily be abused.
Conditional expressions are in a completely different style, with no explicit if in the statement.
The syntax is:
boolean-expression ? expression1 : expression2;
The result of this conditional expression is
expression1 if boolean-expression is true;
otherwise the result is expression2.
Suppose you want to assign the larger number of variable num1 and num2 to max. You can simply write a statement using the conditional expression:
max = (num1 > num2) ? num1 : num2;
Note: The symbols ? and : appear together in a conditional expression. They form a conditional operator and also called a ternary operator because it uses three operands. It is the only ternary operator in Java.
cited from: Intro to Java Programming 10th edition by Y. Daniel Liang page 126 - 127

Java: Syntax error on token "-", Expression expected after this token [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
Well hello guys, i'm starting the programmer life now, i'm really new into it, but i'm trying really, really hard and i'm making some easy programs to run on eclipse console, it's very simples 'cause i'm just getting started... well, everything went out ok, except for this one program, i can't make it work in no way... i'm gonna put it all here so if there's anything really, really wrong tell me, and i'm also going to expecific the problem that eclipse found... Here it is:
public class Pagamento {
public static void main(String[] args) {
int vvalor;
int vpagto;
int vtroco;
String voperador;
vvalor = 200;
vpagto = 250;
voperador = -;
if (vpagto > vvalor){
System.out.println ("Troco:" + vpagto - vvalor);
}if (vpagto = vvalor ){
System.out.println ("Troco:" + 0);
}if (vpagto < vvalor){
System.out.println ("Transação inconcluída!");
}
}
}
I had to define the " - " 'cause it asked to (when i did it, it said in the first System.out.println, that 'the operator - is undefined for the argument type(s) String, int and in the line' "}if (vpagto = vvalor ){" it appeared the error "can't convert from int to boolean), and when i did defined, it just gave this error on the line "voperador = -;":
Syntax error on token "-", Expression expected after this token. What does that mean ? Is everything so wrong ? What should i do to fix it ? Please help me, i try to search but i found nothing like this here, nothing that could solve my problem... thanks and please help !
it should be voperador = "-"; You have missed the double quotes. Strings are required to be enclosed within double qoutes
replace }if (vpagto = vvalor ){
with }if (vpagto ==vvalor ){
Also keep - with in ""(double qoutes) like voperador ="-";
voperador is a String, which can't be assigned to -. If you want the string to be "-", then use voperador = "-";
For your first error: This line isn't valid:
voperador = -;
String constants must go in quotes:
voperador = "-";
A - by itself is either a unary negation operator (e.g. -a) or a binary subtraction operator (e.g. a - b). The error you are seeing is the result of the compiler becoming very confused as to why a negation/subtraction operator was just hanging out between an equal sign and a semicolon.
For your second error: You have this:
if (vpagto = vvalor )
But you should have this:
if (vpagto == vvalor )
In Java, a single = means "assignment". Comparisons are done with the double ==. The reason you saw the error you saw is because Java evaluates the expression a = b to the value of a after the assignment (that's the rule), which in this case happens to be of type int (since vpagto is an int). At the same time, it expects the condition in an if statement to be a boolean (e.g. if (true) ...). The compiler was confused because it wanted a boolean but you gave it an int.
For your third error, you have this:
("Troco:" + vpagto - vvalor)
But what you really mean is this:
("Troco:" + (vpagto - vvalor))
Java evaluates expressions from left to right. As a convenience, it lets you add pretty much anything you want to a string, and the result is a string version of the values you've specified. However, this only works with +, there's no special definition of - for strings. Since it goes left to right, first "Troco:" + vpagto is evaluated, and that is a string. But then you try to subtract vvalor from a string, and the compiler complains. By adding parentheses, you tell it to perform the math on the integers first, before attempting to append the result to a string.
The errors you are making here are very basic. You should really go through the official Language Basics tutorial.

Input validation (do while loop)

I need to make sure the value entered for the prompt is in between 100,000 and 900,000, and this isn't working, any ideas? (I'm only a beginner btw)
double advertCost;
do {
System.out.println("Please enter the advertising cost: ");
advertCost = input.nextDouble();
} while (advertCost =< 100000 || advertCost => 900000);
The error I get:
Syntax error on token "<", delete this token
The operator || is undefined for the argument type(s) int, boolean
Syntax error on token "=", delete this token
Your issue is in your syntax:
while (advertCost =< 100000 || advertCost => 900000);
In Java, the "less than or equal to" operator is as you say it. LESS THAN or EQUAL to. You've got EQUAL TO or LESS THAN. Same goes for your greater than as well. It should look like this:
while (advertCost >= 100000 || advertCost <= 900000);
Also, you had your operators the wrong way around. You want advertCost to be greater than 100000 and less than 900000 but your operators imply less than 100,000 and greater than 900,0000.
Just an aside about your error
Often these sorts of issues can be understood by the error message. I know that they can seem cryptic but if you learn to decipher them, you really will have little need for us in terms of syntax errors.
Syntax error on token "<", delete this token The operator || is undefined for the argument type(s) int, boolean Syntax error on token "=", delete this token
Let's cut it up into it's parts:
The first part
Message:Syntax error on token "<", delete this token
Well, the JRE has just parsed your code, and it is going through each token. This is the first token it has reached that is invalid, so this message is generated. However, if you delete this, you'll still have an invalid if statement, so let's read on.
The second part.
Message:The operator || is undefined for the argument type(s) int, boolean
Well, no detectable operator has been found, so the JRE has to assume there isn't one there. When it has parsed part of the IF statement it's found:
if(a number || something else).
At this point it knows that the || operator only works on two boolean values, so it throws another error. It does this because it already knows the code will fail; it doesn't need to check the other side.
The last part
Message:Syntax error on token "=", delete this token
So the JRE has continued parsing, and it's also found your "=>". As before, it's noted the invalid character and recommended you remove it. If you do remove the "=", then you actually have valid syntax for this part of the If statement.
Summary
Next time you're faced with this type of error, simply try to break down the message. It tells you what characters are wrong, < and =. It even tells you what to try with them. Obviously it can only guess, so it's down to you to work out what you want and how to make the Runtime Environment understand that!
The comparison operators are <= and >=, not =< and =>.
(advertCost <= 100000 || advertCost >= 900000)

What is the Java ?: operator called and what does it do?

I have been working with Java a couple of years, but up until recently I haven't run across this construct:
int count = isHere ? getHereCount(index) : getAwayCount(index);
This is probably a very simple question, but can someone explain it? How do I read it? I am pretty sure I know how it works.
if isHere is true, getHereCount() is called,
if isHere is false getAwayCount() is called.
Correct? What is this construct called?
Yes, it is a shorthand form of
int count;
if (isHere)
count = getHereCount(index);
else
count = getAwayCount(index);
It's called the conditional operator. Many people (erroneously) call it the ternary operator, because it's the only ternary (three-argument) operator in Java, C, C++, and probably many other languages. But theoretically there could be another ternary operator, whereas there can only be one conditional operator.
The official name is given in the Java Language Specification:
§15.25 Conditional Operator ? :
The conditional operator ? : uses the boolean value of one expression to decide which of two other expressions should be evaluated.
Note that both branches must lead to methods with return values:
It is a compile-time error for either the second or the third operand expression to be an invocation of a void method.
In fact, by the grammar of expression statements (§14.8), it is not permitted for a conditional expression to appear in any context where an invocation of a void method could appear.
So, if doSomething() and doSomethingElse() are void methods, you cannot compress this:
if (someBool)
doSomething();
else
doSomethingElse();
into this:
someBool ? doSomething() : doSomethingElse();
Simple words:
booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse
Others have answered this to reasonable extent, but often with the name "ternary operator".
Being the pedant that I am, I'd like to make it clear that the name of the operator is the conditional operator or "conditional operator ?:". It's a ternary operator (in that it has three operands) and it happens to be the only ternary operator in Java at the moment.
However, the spec is pretty clear that its name is the conditional operator or "conditional operator ?:" to be absolutely unambiguous. I think it's clearer to call it by that name, as it indicates the behaviour of the operator to some extent (evaluating a condition) rather than just how many operands it has.
According to the Sun Java Specification, it's called the Conditional Operator. See section 15.25. You're right as to what it does.
The conditional operator ? : uses the boolean value of one expression to decide which of two other expressions should be evaluated.
The conditional operator is syntactically right-associative (it groups right-to-left), so that a?b:c?d:e?f:g means the same as a?b:(c?d:(e?f:g)).
ConditionalExpression:
ConditionalOrExpression
ConditionalOrExpression ? Expression : ConditionalExpression
The conditional operator has three operand expressions; ? appears between the first and second expressions, and : appears between the second and third expressions.
The first expression must be of type boolean or Boolean, or a compile-time error occurs.
condition ? truth : false;
If the condition is true then evaluate the first expression. If the condition is false, evaluate the second expression.
It is called the Conditional Operator and it is a type of Ternary Operation.
int count = isHere ? getHereCount(index) : getAwayCount(index);
means :
if (isHere) {
count = getHereCount(index);
} else {
count = getAwayCount(index);
}
Not exactly correct, to be precise:
if isHere is true, the result of getHereCount() is returned
otheriwse the result of getAwayCount() is returned
That "returned" is very important. It means the methods must return a value and that value must be assigned somewhere.
Also, it's not exactly syntactically equivalent to the if-else version. For example:
String str1,str2,str3,str4;
boolean check;
//...
return str1 + (check ? str2 : str3) + str4;
If coded with if-else will always result in more bytecode.
Ternary, conditional; tomato, tomatoh. What it's really valuable for is variable initialization. If (like me) you're fond of initializing variables where they are defined, the conditional ternary operator (for it is both) permits you to do that in cases where there is conditionality about its value. Particularly notable in final fields, but useful elsewhere, too.
e.g.:
public class Foo {
final double value;
public Foo(boolean positive, double value) {
this.value = positive ? value : -value;
}
}
Without that operator - by whatever name - you would have to make the field non-final or write a function simply to initialize it. Actually, that's not right - it can still be initialized using if/else, at least in Java. But I find this cleaner.
You might be interested in a proposal for some new operators that are similar to the conditional operator. The null-safe operators will enable code like this:
String s = mayBeNull?.toString() ?: "null";
It would be especially convenient where auto-unboxing takes place.
Integer ival = ...; // may be null
int i = ival ?: -1; // no NPE from unboxing
It has been selected for further consideration under JDK 7's "Project Coin."
This construct is called Ternary Operator in Computer Science and Programing techniques. And Wikipedia suggest the following explanation:
In computer science, a ternary operator (sometimes incorrectly called a tertiary operator) is an operator that takes three arguments. The arguments and result can be of different types. Many programming languages that use C-like syntax feature a ternary operator, ?: , which defines a conditional expression.
Not only in Java, this syntax is available within PHP, Objective-C too.
In the following link it gives the following explanation, which is quiet good to understand it:
A ternary operator is some operation operating on 3 inputs. It's a shortcut for an if-else statement, and is also known as a conditional operator.
In Perl/PHP it works as: boolean_condition ? true_value : false_value
In C/C++ it works as: logical expression ? action for true : action for false
This might be readable for some logical conditions which are not too complex otherwise it is better to use If-Else block with intended combination of conditional logic.
We can simplify the If-Else blocks with this Ternary operator for one code statement line.For Example:
if ( car.isStarted() ) {
car.goForward();
} else {
car.startTheEngine();
}
Might be equal to the following:
( car.isStarted() ) ? car.goForward() : car.startTheEngine();
So if we refer to your statement:
int count = isHere ? getHereCount(index) : getAwayCount(index);
It is actually the 100% equivalent of the following If-Else block:
int count;
if (isHere) {
count = getHereCount(index);
} else {
count = getAwayCount(index);
}
That's it!
Hope this was helpful to somebody!
Cheers!
Correct. It's called the ternary operator. Some also call it the conditional operator.
Its Ternary Operator(?:)
The ternary operator is an operator that takes three arguments. The first
argument is a comparison argument, the second is the result upon a true
comparison, and the third is the result upon a false comparison.
Actually it can take more than 3 arguments. For instance if we want to check wether a number is positive, negative or zero we can do this:
String m= num > 0 ? "is a POSITIVE NUMBER.": num < 0 ?"is a NEGATIVE NUMBER." :"IT's ZERO.";
which is better than using if, else if, else.
?: is a Ternary Java Operator.
Its syntax is:
condition ? expression1 : expression2;
Here, the condition is evaluated and
condition returns true, the expression1 will execute.
condition returns false, the expression2 will execute.
public class Sonycode {
public static void main(String[] args) {
double marks = 90;
String result = (marks > 40) ? "passed in exam" : "failed in exam";
System.out.println("Your result is : " + result);
}
}
Output :-
Your result is : passed in exam
It's the conditional operator, and it's more than just a concise way of writing if statements.
Since it is an expression that returns a value it can be used as part of other expressions.
Yes, you are correct. ?: is typically called the "ternary conditional operator", often referred to as simply "ternary operator". It is a shorthand version of the standard if/else conditional.
Ternary Conditional Operator
I happen to really like this operator, but the reader should be taken into consideration.
You always have to balance code compactness with the time spent reading it, and in that it has some pretty severe flaws.
First of all, there is the Original Asker's case. He just spent an hour posting about it and reading the responses. How longer would it have taken the author to write every ?: as an if/then throughout the course of his entire life. Not an hour to be sure.
Secondly, in C-like languages, you get in the habit of simply knowing that conditionals are the first thing in the line. I noticed this when I was using Ruby and came across lines like:
callMethodWhatever(Long + Expression + with + syntax) if conditional
If I was a long time Ruby user I probably wouldn't have had a problem with this line, but coming from C, when you see "callMethodWhatever" as the first thing in the line, you expect it to be executed. The ?: is less cryptic, but still unusual enough as to throw a reader off.
The advantage, however, is a really cool feeling in your tummy when you can write a 3-line if statement in the space of 1 of the lines. Can't deny that :) But honestly, not necessarily more readable by 90% of the people out there simply because of its' rarity.
When it is truly an assignment based on a Boolean and values I don't have a problem with it, but it can easily be abused.
Conditional expressions are in a completely different style, with no explicit if in the statement.
The syntax is:
boolean-expression ? expression1 : expression2;
The result of this conditional expression is
expression1 if boolean-expression is true;
otherwise the result is expression2.
Suppose you want to assign the larger number of variable num1 and num2 to max. You can simply write a statement using the conditional expression:
max = (num1 > num2) ? num1 : num2;
Note: The symbols ? and : appear together in a conditional expression. They form a conditional operator and also called a ternary operator because it uses three operands. It is the only ternary operator in Java.
cited from: Intro to Java Programming 10th edition by Y. Daniel Liang page 126 - 127

Categories

Resources