-
So far we have looked at very simple programs and the basic elements of the code itself. We have seen that Ox has syntax for carrying out mathematical computation like a calculator. It also understands matrices, which is an important aspect of Ox that most general-purpose languages do not.
05-scan.ox 1: #include "oxstd.h" 2: main() { 3: decl x=0; 4: scan("Enter x: %g",&x); 5: println("Ok, x= ",x); 6: }
Note: If you run this program and nothing happens it means you have not set OxEdit to take input. The Ox program is waiting for input that it will never see:
- if ( you-could-read-my-mind ) what-a-tale-my-thoughts-could-tell ♭Gordon Lightfoot 1970
if ( «condition» ) «statement»
The characters « and » are used to indicate that you do not include the word "condition" or "statement". Instead, this means a condition and statement of your choosing goes in those places.
05a-scanX.ox 1: #include "oxstd.h" 2: main() { 3: decl x; 4: scan("Enter x: %g",&x); 5: if (x < 1.0) { 6: println("x is less than 1.0"); 7: println("So we are in trouble"); 8: } 9: else 10: println("We are all set"); 11: println("Finished"); 12: }
This program prints out an extra line of output if the user enters a value less than 1.0. Note that a statement ends with - A Block of Statements in Ox are contained inside
{
and}
{ statement_1; statement_2; ⋮ }
Notice that this use of 05b-scanX.ox 1: #include "oxstd.h" 2: main() { 3: decl x; 4: scan("Enter x: %g",&x); 5: if (x < 1.0) { 6: println("x is less than 1.0"); 7: if (x < 0.0) 8: println("In fact, it is less than 0!"); 9: } 10: println("Finished"); 11: }
Extra whitespace (indentation) is used to make the logic of the program more obvious to a human by indenting statements that are part of the if statement. The indentation does not change the meaning (the semantics) of the program.
- Or Else! In the simple if-then statement nothing special happens when the condition is false. But often we want something different to happen if the condition is false. An equivalent in English might be: "If I study for the exam, then I will pass, else I will fail."
if («condition») «statement» else «statement»
It is a bit tricky if you are new to programming, but you can think of a statement as a block containing statements, so the notion of a statement is recursive.
⋮ scan("Enter x: %g",&x); if (x < 1.0) println("x is less than 1.0"); else println("x is at least as big as 1.0");
Notice that either a if (x < 1.0) println("x is less than 1.0"); else if (x < 2.0) println("x lies between 1.0 and 2.0"); else println("x is at least as big as 2.0");
Each if (x < 1.0) println("x is less than 1.0"); else { if (x < 2.0) println("x lies between 1.0 and 2.0"); else println("x is at least as big as 2.0"); }
decl xispos; scan("Enter x: %g",&x); if (x < 0.0) xispos = FALSE; else xispos = TRUE; ⋮ if (xispos) { // handle positive values } else { // handle negative values }
Notice that the name of the variable - Nested if statements We can think of the "if" and "else" parts of the statement (when there is an else, since that is optional) as "branches" that the program can follow depending on the inputs on this particular run. Each branch is a statement, which can be multiple simple statements surrounded by
decl V scan("Enter V: %g",&V); if (V >= 0) { if (V <= 100 ) { println("V is valid"); } else { println("V is too big"); } } else { println("V is negative"); }
Of course, the program would actually do more than simply print a different message in each case. But the idea is that the flow of the program now creates three different possible paths not just 1 or 2. Your code could nest an if inside an if inside an if which would impose 3 conditions. There could be up to $2^3=8$ different possible paths if each if has an optional else. Learning how to use if statements to match simple logic like "a valid percentage is between 0 and 100". This is not the only way to code this check this condition. For example, if we don't care why $V$ is invalid we could use the logical AND to check both conditions in one if statement:
decl V scan("Enter V: %g",&V); if (V >= 0 && V <= 100) { println("V is valid"); else { println("V is invalid"); }
- The Conditional Expression
… ? … : …
Because setting a value of a variable based on a condition is so standard, Ox has a special kind of operator to do this without using the more flexible xispos = x > 0 ? TRUE : FALSE;
The operation is called the conditional expression and uses the symbols «cond1» ? «val-0» : ( «cond2» ? «val-1» : «val-2»);
Round brackets, new lines and indentation are added here to make it clearer what is happening (but as usual they are not required). Further - Flick-of-the Switch♭AC/DC 1983 A
switch_single ( «integer» ) { case «val-0» : statement-block; case «val-1» : statement-block; ⋮ case «val-k» : statement-block; default : statement-block; }
Several things need to be pointed out. First, instead of testing a condition for being true or false the condition is an integer value so that many different cases can be coded and treated differently. Second, the statement requires switch_single (i) { case 0: println("zero"); case 1: println("one"); case 2: println("two"); default: println("i is something other than 0, 1, or 2"); }
However, everything so far has carried out calculations already determined before the program is running. Another way of saying this is that, so far, the operations have been hard coded
into the .ox
program and not dependent on the data itself.
Now we introduce aspects of Ox that allow a program to be a contingent plan to deal with input that is not known until after the program is running. To make this easier to explain we need a way to provide input to the program that is not hard-coded. There are many ways in Ox to read in data from files, and most serious computational economics would rely on this kind of data input. However, to emphasize reaction to input we introduce the Ox method for asking for input from the keyboard interactively. This method is the scan()
function.
There are two bits of syntax in the program that we will only discuss later, namely %g
and &x
. Essentially, %g
says that the person should enter a real number (not a name or other kind of input), and &x
says to put the number entered into the variable x
.
Our first compound Ox statement is the if
statement. A compound statement is one made up of two or more other statements, just like English. If I study for the test then I can pass the course.
is a sentence made up of two complete sentences with some extra glue that ties them together: the special words if
and then
. An Ox if
statement is similar except you do not include then
in your code.
The simple if
statement has the form
Meanwhile, if
is a keyword that plays the role like an operator even though it is not a symbol. Note that the round brackets are required parts of the syntax. This is often called a if-then
statement, although in Ox there is no then
keyword. Only if
appears, and the then part is whatever comes after ")".
When learning to program, it helps to visualize how the program will execute. A way to this is to create a flowchart for the program. There are standard symbols for structures like an if statement
. In flowcharts, a test of a condition is represented by a diamond shape ◆. The possible results of the test are given by arrows out of the diamond marked Yes
and No
or sometimes TRUE
and FALSE
.
The condition is an expression that is tested for being TRUE or FALSE. If it is TRUE then the statement is executed. If it is FALSE then the statement is skipped and the next statement in the program is executed. Here is an example in Ox:
;
so the then-statement is println("x is less than 1.0");
. Does this mean that you can only do one thing if the condition is true? No, because there is another way to create a complex statement using { … }
, which creates a statement block:
{ }
is different than the use seen earlier to create an oxarray
. Every program we have seen so far has used brackets in a similar way, because the main()
function is defined by the statements between the brackets that follow.
Here the brackets create a single statement from 0 or more statements. A use of brackets to create a more complex program could look like this:
This feature of Ox, that brackets create blocks of code and indentation only helps a human reader is completely different than Python. In Python the indentations matter because they create the blocks of code.
Programming code is sequential. So the if-block comes before the else-block in the code. Only one block will be executed. The computer has to skip or jump over the block that is not executed. Thus, in Ox you have the option of adding an else
component to your if statement. Now the compound statement is formed from two statements (which again can each be blocks of statements). The format is
Here is a simple example in Ox:
;
or a }
must appear before else
because the then part must be a complete statement. And, of course, the else part can be a statement block surrounded by curly brackets. The else part can also be another if-statement (and another and another …):
else
part matches the closest previous if
, but it is much clearer to use curly brackets and indentation to make it clear which if
each else
goes along with:
One of the basic uses of if()
is to make the value of a variable depend on some condition that is checked when the program is running. For example, perhaps the rest of the program does different things depending on whether the value of x
entered from the keyboard is negative or not. Rather than checking it over and over again we can define a variable that carries this information:
xispos
says what information is being stored in it. You should try to come up with names like this in your own program to make them easier for you and others to read them.
{ ... }
. And this means, for example, that the if branch can contain another if ()
statement. That is, if statements can be nested. For example a percentage grade $V$ must satisfy two conditions: $V\ge 0$ and $V\le 100$. So a program to enter and store grades should check these conditions and only accept $V$ if both hold. The flowchart might look like this:
Then in Ox:
The if-then and if-then-else statements are essential parts of Ox and any programming language. The sections below discuss two useful but not necessary features of Ox that allow you to specialize the if statement and simplify many related if-then-else conditions.
if()
.
?
and :
. If the condition (the expression before ?
) is true then the whole thing equals the expression between ?
and :
. If the condition is false the whole thing equals the expression after :
. One reason for using this instead of if()
is that it makes it easier to see that the point is to set the value of xispos
. The operator can be placed in any expression. They can be used in a chain to return 3 or more different values:
? :
can return strings or other non-numerical values as well.
switch
statement is a compact way of writing a sequence of if
statements involving the same variable for comparison. We discuss the simpler version, the switch_single
statement. The more flexible, switch
statement can be see in the Ox syntax documentation.
{ }
to follow the condition. Third, each value of the integer condition is listed as a case
. So «val-0» means the first value you want to handle. It could be -123 or 45 or whatever. Then a colon :
is followed by a statement block to be executed in that case.
Because all the cases are surrounded by { }
the individual statement blocks inside the switch_single
do not require curly brackets around them. Ox knows the block ends once it finds another case
.
You can code as many different cases as you need. But there are a lot of integers so you don't have to provide cases for integers that can't happen in your code. Further, you may be a bunch cases that all result in the same stuff to do. You can say what to do for all other cases by specifying the default
case. The statement block will end once the right bracket that matches the one that started it all is found.
Exercises
scan()
call that asks for the number of rows and columns first; then prompts for r*c numbers; and then stores them in the desired r×c matrix.
06-scanM.ox
1: #include "oxstd.h"
2: main() {
3: decl x, r=2, c = 3, N=r*c;
4: println("Enter ",N," numbers separated by spaces then ENTER");
5: scan("? %#m",r,c,&x);
6: println("Ok, x= ",x);
7: }
07a-FtoC.ox
1: #include "oxstd.h"
2: main() {
3: decl TF, TC;
4: scan("Enter Fahrenheit temperature: %g",&TF);
5: //TC = insert-code-to-convert-to-Celsius
6: print("Ok, ",TF,"F = ",TC,"C ");
7: if (TC<0) println("burrr");
8: }
- Look up the conversion formula F to C and implement on the commented line
TC = ...
. Input the temperatures: -5, 33, 212; use another conversion tool (Google, calculator) to verify the output. - Add a message that if the temperature is above 30C says
hot!
. - Add a message that between 0 and 30 says
nice
.
07b-Fever.ox
1: #include "oxstd.h"
2:
3: // Use const to store constants that appear in formulas, equations, etc.
4:
5: const decl FP , ratio ;
6:
7: main() {
8: decl T, TF, TC,scale;
9: scan("Enter temperature : %g",&T,"%s",&scale);
10: if (scale=="F") {
11: //set TF and TC when T is in Fahrenheit
12: }
13: else if (scale=="C") {
14: //set TF and TC when T is in Celsius
15: }
16: else
17: oxrunerror("scale not recognized");
18: print("Ok, ",TF,"F = ",TC,"C ");
19: if (TF>100.4)
20: println(" Fever ");
21: else
22: println(" Normal ");
23: }
- Modify this code to store the two constants.
- This version also modifies
scan()
so that it asks for both a temperature and a character for the scalar: Use the constants inside thescan("Enter temperature: %g",&T,"%s",&scale);
if() else
to convert from F to C or C to F. Each branch sets the values of both TF and TC so they store the same temperature in each scale. No numbers should appear, just T, FP and ratio. - Modify the function so that the code in the two branches are moved to two functions,
FtoC(tf)
andCtoF(tc)
. Each takes a temperature as its argument and returns the converted temperature. Use this function instead of the inline code.
scan("%g",&x)
in a program to prompt the user to enter a real number. If it is bigger than 0 print out the logarithm of x. If it is less than or equal to 0 return a message that says the log of x is undefined.x
and the conditional expression ? :
to store in another variable 0
if x < 10
, 1
if 10 ≤ x < 100
and 2
if x ≥ 100
.