
-----------------------------------
Cervantes
Fri Dec 29, 2006 6:57 pm

If Statements
-----------------------------------
If Statements

Introduction

In computer science, much like in the English language, if statements are used to make decisions. For example, "if I have $2.95 on me, then I'm going to buy a slice of pepperoni pizza from the caf."  We're going to take this English statement and migrate into Turing code. 

This tutorial aims to teach the semantics of if statements in Turing. We'll lay down some basic rules about the syntax of Turing and from there we will develop a system that allows us to evaluate code in a stepwise manner. 

In general, an if statement in Turing looks like the following:

if expression then
   action
end if


Now, I will lay down two fundamental rules. Assume "" is some Turing code. It could be one line long, or more.

The following two pieces of code are identical:

if true then
    
end if



The following two pieces of code are identical:

if false then
    
end if


That is, the action in code (a) is never executed.


Now, we can write code that matches the code patterns in these two rules, but that won't be very helpful to us. It won't be helpful because this code is as static as the code we could write previously. We still aren't making any decisions. To do this, we need to learn about expressions. I will define an expression, in a kind of wishy-washy way, as anything that can be evaluated, simplified, or reduced down to a value. Values are concrete things: numbers like 5.8, strings like "hello world", true, and false. A mathematical expression such as "5 + 3 / 4" is an expression, because it can be simplified down to a value: 5.75. Here's another example, involving variables: 
var my_money : real := 2.95
put my_money
Evaluating the second line of code is not a one step process. Because "my_money" is an expression, we must first substitute in our value for the "my_money" expression. So the first step in evaluating this would be the following:
var my_money : real := 2.95
put 2.95
And then the second line of code can be taken care of by a special rule in Turing's syntax that says "put " can be handled.

We've now encountered one type of expression: a variable that is bound to some value. However, we still aren't able to write dynamic code--code that makes decisions. We have to look at some more complex expressions, expressions that use "operators".


Expressions using Operators

In computer science, an operator is something that is placed between two "operands". Operands are things like numbers or strings or other data. An operator compares the data on its left to the data on its right and returns a value. Some common operators are equals ("="), and ("&"), or ("|"), greater than (">"), less than ("="), and less than or equal to ("", "= 2.95". We determined this to be false. Since the value of "my_money" is not changed anywhere between the time that we test "my_money >= 2.95" and the time that we test "my_money < 2.95", we know that the second expression, "my_money < 2.95" evaluates to true, since it is the opposite of "my_money >= 2.95" and that expression evaluated to false. So, we shouldn't have to go through the work of comparing "my_money" to 2.95 again, should we? To solve this problem, we'll add to our syntax.

I will now introduce two new rules, just like I gave two rules at the start of this tutorial. Assume  and  are two distinct bits of Turing code.

The following two pieces of code are identical:

if true then
    
else
    
end if


The following two pieces of code are identical:

if false then
    
else
    
end if




With these new semantics, we can now rewrite the pizza example:

var my_money : real := 1.50
var friends_money : real := 10.00
if my_money >= 2.95 then
    put "Me:  I would like to purchase a slice of pizza with pepperoni and green pepper; hold the green olives."
    my_money := my_money - 2.95
else
    put "Me:  Hey, can you buy me a slice of pizza?"
    % Assume friend was a true friend and gave me some money
    put "Friend:  Fine."
    put "Friend:  I would like two slices of pepperoni pizza."
    friends_money := friends_money - 2.95 * 2
end if

Try going through the trace of this in your head.
You'll notice I didn't bother with two variables I had in the previous code: "my_order" and "friends_order". I needed those in the previous code because, unlike when using else, doing the action in the first if statement did not prevent doing the action in the second if statement. So pictures this, in your mind's eye: I write the code that started this section (the one with my_order and friends_order) except I don't use those two variables. Instead, inside the first if statement that tested "my_month >= 2.95", I just decrease my_money by 2.95, then and there. Well then, what would have happened if I had $4.00 on my person? The first expression, "my_money >= 2.95", would be true, so we would execute the code inside that if statement. That would decrease the value of my_money by 2.95, leaving me with $1.05. That's less than $2.95, so when I go to test the second expression, it too is true! Thus, I would have entered both if statements, and my speech would have sounded dumb: "I'll buy myself a slice of pizza. Friend, can you buy me a slice of pizza?" To solve this problem I had to carefully avoid modifying the value of my_money until after both if statements; I did that by introducing new variables: my_order and friends_order. By using else, we don't have any of these problems.

Question Time: Write a program that gets two numbers from the user and determines whether the first number is bigger than, equal to, or less than the second number.
A solution to this problem is found at the end of this tutorial. I suggest you try solving it for yourself before peeking, though. That's how you learn best.

Now I'm going to make the situation in the caf more complicated. 


-----------------------------------
Cervantes
Fri Dec 29, 2006 6:58 pm


-----------------------------------
Many related choices: Elsif

If I've got $2.95 or more on my person, I'm getting a slice of pepperoni pizza. That's my primary choice, for certain. But what if I don't have enough for a pizza, but I do have enough for a bagel, which costs $1.00? I should get the bagel, right? And if I don't even have enough for a begal, then I'll ask my friends to buy me a begal. One way to code this is like so:

var my_money : real := 4.00
var friends_money : real := 10.00
var my_order : real := 0.00
var friends_order : real := 0.00
if my_money >= 2.95 then
    put "Me:  Pizza, please and thank you!"
    my_order := my_order + 2.95
end if
if (my_money < 2.95) & (my_money >= 1.00) then
    put "Me:  I'd like a begal, I suppose."
    my_order := my_order + 1.00
end if
if my_money < 1.00 then
    put "Me:  Hey, would you buy me a begal for lunch?"
    % Assume friend is a true friend and buys me a begal
    put "Friend:  One begal and one pizza slice, please!"
    friends_order := friends_order + 2.95 + 1.00
end if

% Now we pay for our purchases
my_money := my_money - my_order
friends_money := friends_money - friends_order

This works, but again, it's inefficient. For one, I had to do the business with my_order and friends_order. More importantly, we're doing more tests on "my_money" than we need to. Can you see why? The reasons are the same as in the previous example when I introduced "else". Try doing a trace of it in your head.

To fix this, I'll introduce two new rules.

The following two pieces of code are identical:

if true then
    
elsif  then
    
elsif  then
    
...
else
    
end if



The following two pieces of code are identical:

if false then
    
elsif  then
    
elsif  then
    
...
else
    
end if


if  then
    
elsif  then
    
elsif  then
    
...
else
    
end if



With these new rules, we can rewrite the pizza and begal example:

var my_money : real := 0.85
var friends_money : real := 10.00
if my_money >= 2.95 then
    put "Me:  Pizza, please and thank you!"
    my_money := my_money - 2.95
elsif my_money >= 1.00 then
   put "Me:  I'd like a begal, I suppose."
   my_money := my_money - 1.00
else
   put "Me:  Hey, would you buy me a begal for lunch?"
   % Assume friend is a true friend and buys me a begal
   put "Friend:  One begal and one pizza slice, please!"
   friends_money := friends_money - 2.95 - 1.00
end if

Notice, once again, that I didn't have to bother with my_order or friends_order.

Now, I'll do a trace on this. It will be rather long, but it's worthwhile, because being able to trace through a program properly is crucial when debugging. Here's the trace:

var my_money : real := 0.85
var friends_money : real := 10.00
if my_money >= 2.95 then
    put "Me:  Pizza, please and thank you!"
    my_money := my_money - 2.95
elsif my_money >= 1.00 then
   put "Me:  I'd like a begal, I suppose."
   my_money := my_money - 1.00
else
   put "Me:  Hey, would you buy me a begal for lunch?"
   % Assume friend is a true friend and buys me a begal
   put "Friend:  One begal and one pizza slice, please!"
   friends_money := friends_money - 2.95 - 1.00
end if


var my_money : real := 0.85
var friends_money : real := 10.00
if 0.85 >= 2.95 then
    put "Me:  Pizza, please and thank you!"
    my_money := my_money - 2.95
elsif my_money >= 1.00 then
   put "Me:  I'd like a begal, I suppose."
   my_money := my_money - 1.00
else
   put "Me:  Hey, would you buy me a begal for lunch?"
   % Assume friend is a true friend and buys me a begal
   put "Friend:  One begal and one pizza slice, please!"
   friends_money := friends_money - 2.95 - 1.00
end if


var my_money : real := 0.85
var friends_money : real := 10.00
if false then
    put "Me:  Pizza, please and thank you!"
    my_money := my_money - 2.95
elsif my_money >= 1.00 then
   put "Me:  I'd like a begal, I suppose."
   my_money := my_money - 1.00
else
   put "Me:  Hey, would you buy me a begal for lunch?"
   % Assume friend is a true friend and buys me a begal
   put "Friend:  One begal and one pizza slice, please!"
   friends_money := friends_money - 2.95 - 1.00
end if


var my_money : real := 0.85
var friends_money : real := 10.00
if my_money >= 1.00 then
   put "Me:  I'd like a begal, I suppose."
   my_money := my_money - 1.00
else
   put "Me:  Hey, would you buy me a begal for lunch?"
   % Assume friend is a true friend and buys me a begal
   put "Friend:  One begal and one pizza slice, please!"
   friends_money := friends_money - 2.95 - 1.00
end if


var my_money : real := 0.85
var friends_money : real := 10.00
if 0.85 >= 1.00 then
   put "Me:  I'd like a begal, I suppose."
   my_money := my_money - 1.00
else
   put "Me:  Hey, would you buy me a begal for lunch?"
   % Assume friend is a true friend and buys me a begal
   put "Friend:  One begal and one pizza slice, please!"
   friends_money := friends_money - 2.95 - 1.00
end if


var my_money : real := 0.85
var friends_money : real := 10.00
if false then
   put "Me:  I'd like a begal, I suppose."
   my_money := my_money - 1.00
else
   put "Me:  Hey, would you buy me a begal for lunch?"
   % Assume friend is a true friend and buys me a begal
   put "Friend:  One begal and one pizza slice, please!"
   friends_money := friends_money - 2.95 - 1.00
end if


var my_money : real := 0.85
var friends_money : real := 10.00
put "Me:  Hey, would you buy me a begal for lunch?"
% Assume friend is a true friend and buys me a begal
put "Friend:  One begal and one pizza slice, please!"
friends_money := friends_money - 2.95 - 1.00

And now we're on familiar ground.

Question Time: Write a program that gets three numbers from the user and determines the value of the largest number.
A solution to this problem is found at the end of this tutorial


Conclusion

By now, you should be able to write dynamic programs--programs that can make decisions. You can execute different bits of code depending on what state your program is in. This is vital. As you continue to learn about Turing and about computer science in general, you will continue to see if statements making their presence known. 

Also, this tutorial taught some basic semantics of Turing. These are the rules by which a Turing program can be traced and clarity made of otherwise confusing code. The ability to trace code is essential when trying to understand code. The code may or may not be your own. You might be trying to debug your code or trying to understand someone else's code. Regardless, tracing code is a fundamental tool that you will need.



Solutions
Here are possible solutions to the two problems given in this tutorial.

Problem 1: Comparing two numbers:

var num1, num2 : int
put "Enter number 1: " ..
get num1
put "Enter number 2: " ..
get num2

if num1 > num2 then
    put num1, " is bigger than ", num2
else
    if num1 = num2 then
        put num1, " is equal to ", num2
    else
        put num1, " is smaller than ", num2
    end if
end if

Problem 1: Comparing two numbers, using elsif:

var num1, num2 : int
put "Enter number 1: " ..
get num1
put "Enter number 2: " ..
get num2

if num1 > num2 then
    put num1, " is bigger than ", num2
elsif num1 = num2 then
    put num1, " is equal to ", num2
else
    put num1, " is smaller than ", num2
end if

Problem 2: Finding the biggest of three numbers:

var num1, num2, num3 : int
put "Enter number 1: " ..
get num1
put "Enter number 2: " ..
get num2
put "Enter number 3: " ..
get num3

if num1 > num2 then
    if num2 >= num3 or num1 >= num3 then
        put num1
    else
        put num3
    end if
else
    if num1 >= num3 or num2 >= num3 then
        put num2
    else
        put num3
    end if
end if



Disclaimer:
Actual price of slice of pepperoni pizza may vary.  My caf sucks, except for the breakfast special.

-----------------------------------
Hackmaster
Fri Dec 29, 2006 7:30 pm


-----------------------------------
Cervantes! yet another awe-inspiring tutorial! glad you got this one out!  :lol: 

keep up the good work!!

-----------------------------------
zylum
Thu Jan 04, 2007 3:08 am


-----------------------------------
very nice  :) 

you might want to add the xor operator though:

%returns true if an odd number of arguments is true
put true xor false
put true xor false xor true xor true xor false 

%returns false since an even amount of arguments is true
put true xor true
put false xor false
put true xor true xor false

-----------------------------------
Cervantes
Thu Jan 04, 2007 1:59 pm


-----------------------------------
I was thinking about it, but I figured that won't be of any immediate use. Your bitwise operators tutorial handles it, I think.

-----------------------------------
Megatokyoguy
Mon May 14, 2007 9:01 am

RE:If Statements
-----------------------------------
I am currently working on Turing in class and I loved your previous tutorial (even though I know all that already - I am trying to learn about making games because I have a program that came with turing but I do not understand all the components)

I don't get the "Expressions using Operators"

Very confusing for me.....

-----------------------------------
Cervantes
Mon May 14, 2007 11:11 pm

RE:If Statements
-----------------------------------
Can you be more specific about what you didn't understand? Really, it shouldn't be hard stuff. If you have any experience with basic math, this section should come pretty naturally. If give me some specifics, though, I'll gladly help you out. :)

-----------------------------------
bawler27
Sat Mar 08, 2008 7:52 pm

Re: If Statements
-----------------------------------
nice tut, it helped me out alot! now i can understand half the programs on the forums but there is one thing bothering me.
there was this one program that used 

var+=var

what does that mean or do?

-----------------------------------
Mackie
Sat Mar 08, 2008 8:12 pm

RE:If Statements
-----------------------------------
var += var
Is the same as
var := var + var


But, a better example would be.

a += b
a := a + b

There are others as well.

a -= b
a /= b
a *= b
a div= b
a mod= b

-----------------------------------
Sean
Sat Mar 08, 2008 10:01 pm

Re: If Statements
-----------------------------------
if you were doing var += var then
you are just adding the variable to itself, but you could do..


var += 2


Which increases the variable by 2, instead of increasing it by itself.

-----------------------------------
bawler27
Sun Mar 09, 2008 9:28 am

Re: If Statements
-----------------------------------
oh, it all makes sense now, thx alot guys  :D !!!
