4.0
Flow Control
4.1
If-Elif-Else
The if, elif, and else statements provide the ability
to selectively control which Prothon statements get executed and which
don't. They do this by evaluating an expression and based on the results
they conditionally execute code blocks.
The
particular expressions used by the if-elif-else statements aways result
in one of two particular exact objects. One is the "True"
object and one is the "False" object. These objects are special
one-of-a-kind objects that are different from types like integers and
strings. They do not hold a data value, they just exist.
You
might be wondering how expressions can result in these exact objects.
The answer is that there are many functions that are special that return
only these "True" or "False" objects. These functions
all have names that end in a question mark like the dictionary function
dict.hasKey_?(key). This returns True if the dictionary has the key
and False if it doesn't. If you write a "question" function
that always returns only True or False, then you should end the name
in a question mark also.
There
is one very special "question" function called obj.bool_?()
that can be called on any object of any type and that type decides whether
that object should be considered True or False. For example, the numeric
types consider the number zero to be False and all other numbers to
be True (just like the C language). Likewise, lists and strings are
considered False is they are empty and True otherwise. Each type can
conveniently define what is True or False for it's objects.
Let's
look at how you use the if-elif-else statement. This example shows the
different parts of the statement. The "if" expression is always
tested. If its expression returns True then its block is executed and
all the other parts are skipped over. The "elif" expression
is evaluated if all the expressions before return False and then its
block is executed if it returns True just like the "if". The
"else" block is executed if all expressions before return
False.
# Prothon source file tut4.pr
if True:
print "Hello World"
if False:
print "I'm invisible"
if False:
print 'not this one'
else:
print 'This is the one'
if 0:
print 'not 0, it is false'
elif "":
print 'not "", it is false also'
elif []:
print 'not [] either'
else:
print "All the others are false, so I'm the one"
if 'x'+"abc":
if 7**3:
print "Many things are true"
Here is the output of running the file tut4.pr above:
Hello World
This is the one
All the others are false, so I'm the one
Many things are true
4.2
For Statement
The "for" statement allows you to repeat a block of code
multiple times. It also allows you to assign one or more data variable
values for each time the code runs.
The
"for" statement is very flexible. Unlike other languages it
does not work with a fixed variable type like an integer that it counts
through or a list of items. Like the if-elif-else statement is uses
a special type of function call that allows any type object to specify
what should be done in the "for" statement. This call is obj.next_().
Any
object type can define .next_() just like object types defined .bool_?()
to define what was True and False for the the "if" statement.
When an object type defines .next_() that type of object is called an
"iterator" type. You can call the "iterator object"
with .next_() and it will return a result object over and over for each
call until it is done, at which time it signals that it is done with
an exception (we will discuss exceptions later).
Some
examples of common iterator types are integer-iterators which return
the numbers 0, 1, 2, ... up to the value of the integer-1, string iterators
which return the characters in a string, and a list iterator which returns
the elements in a list. The for list makes it easy to loop once for
each value returned by the iterator, so you can loop n times as an integer
counts up, loop once for each character in a string, or loop once for
each item in a list, etc.
The
for statement is of the form "for vars in iter: block" where
vars are names to assign to the results of the .next_() call on each
iteration of the loop and iter is the iterator object. (Actually the
object that is used to call .next_() on is an iterator that is generated
from iter, not iter itself, but I'm sure these details are starting
to bore you). Block is the code that is executed repeatedly. Here is
some sample code:
# Prothon source file tut5.pr
for i in 3:
print i
print 'i =', i # i is still valid from loop
for c in "abc": # ending print with comma
print c, # suppresses newline at end
print
list = [0, 'a', 3.7]
for item in list:
print item,
print
d = {1:2, 3:4, 5:6}
for t in d.items():
print t[0],t[1]
The results of running this file are:
0
1
2
i = 2
a b c
0 a 3.7
1 2
3 4
5 6
4.3
While Statement
The
"while" statement is a looping statement to repeat blocks
of code like the "for" statement, but it is actually more
similar in structure to the "if" statement. It has an expression
that it evaluates and it repeats the block every time that statement
evaluates to True and finishes when it returns False.
# Prothon source file tut6.pr
i = 0
while i < 3:
print i
i = i + 1
d = {1:2, 3:4, 5:6}
while Len(d):
print d.popItem!()
Results of running tut6.pr:
0
1
2
(1, 2)
(3, 4)
(5, 6)
4.3
Break, Continue, & Else
The "for" and "while" loops have a number of ways
to terminate the looping early before the normal ending. Two of these
ways are the use of the "break" and "continue" statements.
Since these statements interfere with the looping, they are usually
located in a conditional "if" statement and are executed in
certain situations only.
The
break statement stops the execution of code in the current block and
stops the looping. Execution continues after the looping block. If code
is executing in blocks nested several deep from the looping block then
the execution jumps out of all the blocks to the outside of the looping
block attached to the "for" or "while" statement.
In the "for" loop, the loop vars that we set by the .next()
call will remain set to the value they had when the break was executed.
Continue
stops code executing at the continue statement also but execution begins
again at the top of the looping block after another call to the iterator
with .next_() has been made if in a "for" loop, or after the
"while" expression has been checked in a "while"
loop. One way to look at the "continue" statement is that
it jumps to the end of the loop block so that it can start another loop.
Both
the "for" and the "while" statements can optionally
have a "nametag" before the word "for" or the word
"while" in their statements. This tag must be written like
any variable name and be seperated from the "for" or "while"
by a colon. Then the "break" and "continue" statements
can optionally specify which loop they want to break out of or continue
by adding this nametag as a parameter. This is very useful if the break
is nested inside several loops and you want to break out of more than
one of them at once.
The
"for" and "while" statements can also have an "else"
statement and code block added to the end like the "if" statement
has. This "else" code block is executed if the associated
loop executes normally without a break command interrupting it. This
is useful if the loop is searching for something and the break command
is used when the thing searched for is found. The "else" block
can give an error saying the search failed.
Here
is some sample code using break, continue, and else:
# Prothon source file tut7.pr
i = 10
while True:
i = i - 1
if i % 2 == 0: # is i an even number?
continue # then start next loop
if i < 0: # is i a negative number?
break # then quit
print i,
print
a: for i in 10:
for j in 10:
for k in 10:
if i==1 and j==2 and k==3:
break a
else:
print 'this will not print'
print i,j,k
for i in 10:
j = i
else:
print 'this will print', j
Here is what that file printed:
9 7 5 3 1
1 2 3
this will print 9
|