C6. Taking decisions using conditionals and more about loops
Contents
C6. Taking decisions using conditionals and more about loops#
Conditionals#
Till now, our codes have a linear flow: the statements are executed from the start to the end, even within loops. Now, we will learn about conditionals and how they can break this linearity.
A computer can store information, using zeros and ones, but they also have a robust logic system based on boolean algebra. As a result, they can perform complex tasks; even beating the world champion of chess. This happens because they can take decisions. That is, for performing complex tasks, computers need to break the linearity within the code:
Conditionals are statements (commands) used in our programs to make decisions. They are able to control the flow of our code
Boolean data type#
Boolean variables can have two different values:
True
False
The logic of computers is based on this#
Because of the way they are built (electronics): voltage on/off, 1/0, True/False
# True or False
# Be careful, the first letter is uppercase
# The next is not valid: true, false
print(True) # and no quotes: a boolean not a str
print(False)
True
False
# a variable
boolean_var = True
print(boolean_var)
True
Relational operators#
They are used to evaluate
Obtaining a boolean variable: True or False
Symbol |
Evaluation |
---|---|
< |
less than |
<= |
less than or equal to |
> |
greater than |
>= |
greater than or equal to |
== |
equal to |
!= |
not equal to |
is |
object identity |
is not |
negated object identity |
Note that “==” has nothing to do with “=”
Examples#
Think on each result and code to see if you are correct. Also try your own examples
5 < 3
5 > 3
7 > 13
0.1 <= 1
5 == 55
3 != 4
# For the sake of an easy reading
print('5 < 3:', 5 < 3)
print('5 > 3:', 5 > 3)
print('7 > 13:', 7 > 13)
print('0.1 <= 1:', 0.1 <= 1)
print('5 == 55:', 5 == 55)
print('3 != 4:', 3 != 4)
5 < 3: False
5 > 3: True
7 > 13: False
0.1 <= 1: True
5 == 55: False
3 != 4: True
More complex examples using functions and methods#
Try the next examples
len("ATCG") == 4
len("ATCGA") != 5
"CAGCAGCAGG".count('CAG') == 3
"CAGCAGCAGG".count('G') != 4
# For the sake of clarity, but type it. Do not cp and paste
print('len("ATCG") == 4:', len("ATCG") == 4)
print('len("ATCGA") != 5:', len("ATCGA") != 5)
print('"CAGCAGCAGG".count("CAG") == 3:', "CAGCAGCAGG".count('CAG') == 3)
print('"CAGCAGCAGG".count("G") != 4', "CAGCAGCAGG".count('G') != 4)
len("ATCG") == 4: True
len("ATCGA") != 5: False
"CAGCAGCAGG".count("CAG") == 3: True
"CAGCAGCAGG".count("G") != 4 False
New str methods that returns a boolean#
True or False
"ATCG".startswith("ATG")
"ATCG".startswith("DR")
"ATCGATAG".endswith("TAG")
"ATCGATAG".endswith("JR")
"ATCGATAG".isupper()
"ATCGATAG".ilower()
# For the sake of clarity:
print('"ATGCG".startswith("ATG"):', "ATGCG".startswith("ATG"))
print('"ATGCG".startswith("DR"):', "ATCG".startswith("DR"))
print('"ATCGATAG".endswith("TAG"):', "ATCGATAG".endswith("TAG"))
print('"ATCGATAG".endswith("JR"):', "ATCGATAG".endswith("JR"))
print('"ATCGATAG".isupper():', "ATCGATAG".isupper())
print('"ATCGATAG".islower():', "ATCGATAG".islower())
"ATGCG".startswith("ATG"): True
"ATGCG".startswith("DR"): False
"ATCGATAG".endswith("TAG"): True
"ATCGATAG".endswith("JR"): False
"ATCGATAG".isupper(): True
"ATCGATAG".islower(): False
# You should always try more examples, like
print('"ATcgATAG".isupper():', "ATcgATAG".isupper())
print('"ATCGAtAG".islower():', "ATCaGAgAG".islower())
"ATcgATAG".isupper(): False
"ATCGAtAG".islower(): False
Membership test operators#
in and not in
Membership test operations
**************************
The operators "in" and "not in" test for membership.
"x in s" evaluates to "True" if *x* is a member of *s*,
and "False" otherwise "x not in s" returns the negation of "x in s".
# not in: against the same list
print('M' not in ['A','C','D','E','F','G','H','I','K','L','M','N','P','Q','R','S','T','V','W','Y'])
False
# not in: against the same list
print('M' not in ['A','C','D','E','F','G','H','I','K','L','M','N','P','Q','R','S','T','V','W','Y'])
False
# not here
print('X' in ['A','C','D','E','F','G','H','I','K','L','M','N','P','Q','R','S','T','V','W','Y'])
False
# check in a str
"c" in "ATCG"
False
# Now it is here
"C" in "ATCG"
True
Note: do not confuse with the in in the loop (for)
for x in y:
body of the for
if: building a conditional statement#
Makes a decision
if condition then
# See an example:
aa = "M"
if aa != "V": # if condition then
print(aa, "is not Valine")
M is not Valine
Parts of an if statement#
* First line of the if:
- **if**
- __condition__
- **:**
* Body of the if:
- **block of indented lines**
# Example:
for aa in ['A','C','D','E','F','G','H','I','K','L','M','N','P','Q','R','S','T','V','W','Y']:
if aa in ['V','I','L','M','F','W','C']: # A more complicated condition
print(aa, "is hydrophobic") # this line is double indexed (for and if)
C is hydrophobic
F is hydrophobic
I is hydrophobic
L is hydrophobic
M is hydrophobic
V is hydrophobic
W is hydrophobic
continue, break and pass#
in combination with if. They help to build very useful statements within loops (ie. for)
continue#
# continue: jumps to the next iteration
aas1 = ['A','C','D','E','F']
aas2 = ['G','H','I','K','L','M','N','P','Q','R','S','T','V','W','Y']
for aa in aas1 + aas2: # + concatenates the two lists
if aa in aas2: # but 5 first elems
continue
print(aa, "reached")
print("...Out of the loop")
A reached
C reached
D reached
E reached
F reached
...Out of the loop
break#
# break: jumps out of the loop
aas = ['A','C','D','E','F','G','H','I','K','L','M','N','P','Q','R','S','T','V','W','Y']
for aa in aas:
if aa == 'M':
break
print(aa, "reached")
print("...Out of the loop")
A reached
C reached
D reached
E reached
F reached
G reached
H reached
I reached
K reached
L reached
...Out of the loop
pass#
# pass: is a null statement.
# It means: still I do not know which code should be writen there
aas1 = ['A','C','D','E','F']
aas2 = ['G','H','I','K','L','M','N']
aas3 = ['P','Q','R','S','T','V','W','Y']
for aa in aas1 + aas2 + aas3:
if aa in aas1 + aas3:
pass # placeholder: It will be written later. At the moment do nothing
else:
print(aa, "reached")
print("...Out of the loop")
G reached
H reached
I reached
K reached
L reached
M reached
N reached
...Out of the loop
else#
Means otherwise and makes a decision:
if condition:
body_of_if
else:
body_of_else
# classifying amino_acids because of chemical properties
aa_list = ['A','C','D','E','F','G','H','I','K','L','M','N','P','Q','R','S','T','V','W','Y'] # 20 aa
sulphur_containing_list = ['M', 'C'] # Methione, Cysteine
for aa in aa_list:
if aa in sulphur_containing_list: #
print(aa, "contains sulphur")
else: # Otherwise: if it is NOT in the 1st list
print(aa, "does NOT contain sulphur")
A does NOT contain sulphur
C contains sulphur
D does NOT contain sulphur
E does NOT contain sulphur
F does NOT contain sulphur
G does NOT contain sulphur
H does NOT contain sulphur
I does NOT contain sulphur
K does NOT contain sulphur
L does NOT contain sulphur
M contains sulphur
N does NOT contain sulphur
P does NOT contain sulphur
Q does NOT contain sulphur
R does NOT contain sulphur
S does NOT contain sulphur
T does NOT contain sulphur
V does NOT contain sulphur
W does NOT contain sulphur
Y does NOT contain sulphur
We can use else to divide in more than 2 sets. See the next example with 3 sets:
# We divide the digits in 3 sets
digit_list = list(range(0, 10, 1)) # a list of digits
for digit in digit_list:
if digit <= 3:
print(digit, "is <= 3")
else:
if digit <= 7:
print(digit, "is >3 and <=7")
else:
print(digit, "is >7")
0 is <= 3
1 is <= 3
2 is <= 3
3 is <= 3
4 is >3 and <=7
5 is >3 and <=7
6 is >3 and <=7
7 is >3 and <=7
8 is >7
9 is >7
elif#
Combination of else and if. Also makes a decision:
if condition_1:
body_of_if
elif condition 2: # (not condition_1) and condition_2
body_of_elif
else: # otherwise => (not condition_1) and (not condition_2)
body_of_else
The previous example
# We divide the digits in 3 sets
digit_list = list(range(0, 10, 1)) # a list of digits
for digit in digit_list:
if digit <= 3:
print(digit, "is <= 3")
elif digit <= 7:
print(digit, "is >3 and <=7")
else:
print(digit, "is >7")
0 is <= 3
1 is <= 3
2 is <= 3
3 is <= 3
4 is >3 and <=7
5 is >3 and <=7
6 is >3 and <=7
7 is >3 and <=7
8 is >7
9 is >7
We can even use “elif” to classify in more sets. For instance in 5 sets:
# We divide the digits in 5 sets
digit_list = list(range(0, 10,1)) # a list of digits
for digit in digit_list:
if digit <= 1:
print(digit, "is <= 1")
elif digit <= 3:
print(digit, "is >1 and <=3")
elif digit <= 5:
print(digit, "is >3 and <=5")
elif digit <= 7:
print(digit, "is >5 and <=7")
else:
print(digit, "is >7")
0 is <= 1
1 is <= 1
2 is >1 and <=3
3 is >1 and <=3
4 is >3 and <=5
5 is >3 and <=5
6 is >5 and <=7
7 is >5 and <=7
8 is >7
9 is >7
Nesting “if”, “elif” and “else”#
We can nest “if”, “elif” and “else” to classify complex sets
Functions that return a boolean type: True or False#
Their outputs can be used in conditionals
def is_GC_rich(dna):
GC_content = (dna.count('G') + dna.count('C')) / len(dna)
if GC_content > 0.65:
return True
else:
return False
# main
print(is_GC_rich("ATCGCGCGACCGG"))
print(is_GC_rich("ATCTCGCGATTCCGCT"))
True
False
Booleans#
Boolean operators: and, or, not#
This is very important because more complex conditions can be build
and#
accs = ['ab56', 'bh84', 'hv76', 'ay93', 'ap97', 'bd72']
for accession in accs:
if accession.startswith('a') and accession.endswith('3'):
print(accession)
ay93
or#
accs = ['ab56', 'bh84', 'hv76', 'ay93', 'ap97', 'bd72']
for accession in accs:
if accession.startswith('a') or accession.startswith('b'):
print(accession)
ab56
bh84
ay93
ap97
bd72
not#
accs = ['ab56', 'bh84', 'hv76', 'ay93', 'ap97', 'bd72']
for accession in accs:
if not accession.startswith('a'):
print(accession)
bh84
hv76
bd72
operator precedence#
not, and, or: from highest to lower precedence
# example of precedence: 1.not, 2.and
accs = ['ab56', 'bh84', 'hv76', 'ay93', 'ap97', 'bd72']
for accession in accs:
if not accession.startswith('a') and accession.startswith('b'):
print(accession)
bh84
bd72
# example of precedence: 1.not, 2.and
accs = ['ab56', 'bh84', 'hv76', 'ay93', 'ap97', 'bd72']
for accession in accs:
if not accession.startswith('a') or accession.startswith('b'):
print(accession)
bh84
hv76
bd72
# example of precedence: 1.and, 2.or
accs = ['ab56', 'bh84', 'hv76', 'ay93', 'ap97', 'bd72']
for accession in accs:
if accession.startswith('a') or accession.startswith('b') and accession.startswith('b'):
print(accession)
ab56
bh84
ay93
ap97
bd72
Combining the boolean operators: and, or, not#
to build any logic expression (boolean algebra)
Loops#
while#
It loops while a condition is True
while condition:
indented_body_of_while
# example of while
digit = 0
while digit < 10:
print(digit)
digit += 1 # digit = digit + 1
0
1
2
3
4
5
6
7
8
9
# The last while is equivalent to:
for digit in range(0,10):
print(digit)
0
1
2
3
4
5
6
7
8
9
Summary#
Conditional:
Boolean variable type:
True
False
Relational operators (==, !=, >, …)
str.methods returning a boolean
Membership (in, not in)
if, else, elif
boolean operators:
and
or
not
Loops:
while