Python: complex statements (Solutions)¶
Conditional code: if
¶
Solution:
number = int(raw_input("write a number: ")) if number % 2 == 0: print "even" else: print "odd"
We use
else
, since even and odd are the only two possibilities.A way to make a third option explicit would be:
if number % 2 == 0: print "even" elif number % 2 == 1: print "odd" else: print "impossible!"
but the code in
else
will never be executed for any value ofnumber
!Since the two options are mutually exclusive, we can also write:
if number % 2 == 0: print "even" if numero % 2 == 1: print "odd"
even without the``else``, one and only one of the
if
can be executed.Solution:
number = float(raw_input("write rational: ")) if number >= -1 and number <= 1: print "okay"
we don’t need neither``elif`` (there is only one condition) neither
else
(if the condition is false, we don’t need to do anything).Solution:
answer = raw_input("write two numbers separated by a space: ") words = answer.split() num1 = int(words[0]) num2 = int(words[1]) if num1 > num2: print "first" elif num2 > num1: print "second" else: print "neither"
Alternatively:
answer = raw_input("write two numbers separated by a space: ") numbers = [int(word) for word in answer.split()] if numbers[0] > numbers[1]: print "first" elif numbers[0] < numbers[1]: print "second" else: print "neither"
Solution:
horoscope_of = { "January": "extreme luck", "February": "try to be born again", "March": "kissed by fortune", "April": "lucky luke", } month = raw_input("tell me your birth month: ") if horoscope_of.has_key(month): print horoscope_of[month] else: print "not available"
Solution:
path = raw_input("write your path: ") lines = open(path, "r").readlines() if len(lines) == 0: print "empty" elif len(lines) < 100: print "short", len(lines) elif len(lines) < 1000: print "average", len(lines) else: print "large", len(lines)
Note that it’s not necessary to specify entirely the conditions: in the code we can shorten
100 < len(lines) < 1000
withlen(lines) < 1000
. We can do that, since when``len(lines)`` is lower than100
the firstelif
is executed: the secondelif
is not even considered.Solution:
point1 = [float(word) for word in raw_input("write three coordinates: ").split()] point2 = [float(word) for word in raw_input("write three coordinates: ").split()] if point1[0] >= 0 and point1[1] >= 0 and point1[2] >= 0 and \ point2[0] >= 0 and point2[1] >= 0 and point2[2] >= 0: diff_x = point1[0] - point2[0] diff_y = point1[1] - point2[1] diff_z = point1[2] - point2[2] print "the distance is", (diff_x**2 + diff_y**2 + diff_z**2)**0.5
Note that
print
is inside theif
.Solution: we know that
number
is an arbitrary integer, chosen by the user:if number % 3 == 0: print "divisible by 3" elif numero % 3 != 0: print "not divisible by 3" else: print "dunno"
if
,elif
andelse
form a chain: only one among them is executed.if
is executed if and only ifnumber
is divisibile by three.elif
is executed if and only if the previousif
is not executed and ifnumber
is not divisible by three.else
is execute whenever neitherif
andelif
are executed.
Since all numbers are either divisible by
3
either not, there is no other possibility,else
will never be executed.Therefore, the answer is no.
Solution: as before,
number
is an arbitrary integer. The code is:number = int(raw_input("write a number: ")) if number % 2 == 0: print "divisible by 2" if number % 3 == 0: print "divisible by 2" if number % 2 != 0 and number % 3 != 0: print "dunno"
Here we don’t have “chains” of
if
,elif
edelse
: we have three independentif
.- The first
if
is executed if and only ifnumber
is divisible by two. - The second
if
is executed if and only ifnumber
is divisible by three. - The third
if
is executed if and only ifnumber
is not divisible by neither two and three.
If
number
is 6, divisible by both two and three, the first twoif
will be both executed, while the third won’t be.If
number
is 5, not divisible by neither two and three, the first twoif
will not be executed, but the third will be.Therefore, the answer is yes.
(There is no possibility to not execute neither of the three
if
.)- The first
Solution:
answer = raw_input("sum or product?: ") if answer == "sum": num1 = int(raw_input("number 1: ")) num2 = int(raw_input("number 2: ")) print "the sum is", num1 + num2 elif answer == "product": num1 = int(raw_input("num1: ")) num2 = int(raw_input("num2: ")) print "the product is", num1 * num2
Using
if
orelif
won’t change the execution of the program.We can simplify like this:
answer = raw_input("sum or product?: ") num1 = int(raw_input("number 1: ")) num2 = int(raw_input("number 2: ")) if answer == "sum": print "the sum is", num1 + num2 elif answer == "product": print "the product is", num1 * num2
Iterative code: for
and while
¶
Solutions:
Solution:
for number in range(10): print number
Solution:
for number in range(10): print number**2
Solution:
sum_of_squares = 0 for number in range(10): sum_of_squares = sum_of_squares + number**2 print sum_of_squares
Solution:
product = 1 # note that for the product the initial value should be 1! for number in range(1,10): product = product * number print product
Solution:
volume_of = { "A": 67.0, "C": 86.0, "D": 91.0, "E": 109.0, "F": 135.0, "G": 48.0, "H": 118.0, "I": 124.0, "K": 135.0, "L": 124.0, "M": 124.0, "N": 96.0, "P": 90.0, "Q": 114.0, "R": 148.0, "S": 73.0, "T": 93.0, "V": 105.0, "W": 163.0, "Y": 141.0, } sum_of_volumes = 0 for volume in volume_of.values(): sum_of_volumes = sum_of_volumes + volume print sum_of_volumes
Solution:
volume_of = { "A": 67.0, "C": 86.0, "D": 91.0, "E": 109.0, "F": 135.0, "G": 48.0, "H": 118.0, "I": 124.0, "K": 135.0, "L": 124.0, "M": 124.0, "N": 96.0, "P": 90.0, "Q": 114.0, "R": 148.0, "S": 73.0, "T": 93.0, "V": 105.0, "W": 163.0, "Y": 141.0, } fasta = """>1BA4:A|PDBID|CHAIN|SEQUENCE DAEFRHDSGYEVHHQKLVFFAEDVGSNKGAIIGLMVGGVV""" # Let's extract the sequence sequence = fasta.split("\n")[1] sum_of_volumes = 0 # for each character in the sequence ... for aa in sequence: volume_of_aa = volume_of[aa] sum_of_volumes = sum_of_volumes + volume_of_aa print sum_of_volumes
Solution: let’s adapt the code from the previous example:
list = [1, 25, 6, 27, 57, 12] minimum_so_far = list[0] for number in list[1:]: if number < minimum_so_far: minimum_so_far = number print "the minimum value is:", minimum_so_far
Solution: let’s combine the example and the previous exercise:
list = [1, 25, 6, 27, 57, 12] max = list[0] min = list[0] for number in list[1:]: if number > max: max = number if number < min: min = number print "minimum =", min, "maximum =", max
Solution:
range(0, len(sequence), 3)
returns[0, 3, 6, 9, ...]
, containing the positions of the first character of all the triplets.Let’s write:
sequence = "ATGGCGCCCGAACAGGGA" # let's start from an empty list triplets = [] for pos_start in range(0, len(sequence), 3): triplets = sequence[pos_start:pos_start+3] triplets.append(triplets) print triplets
Solution:
text = """>2HMI:A|PDBID|CHAIN|SEQUENCE PISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKI >2HMI:B|PDBID|CHAIN|SEQUENCE PISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKI >2HMI:C|PDBID|CHAIN|SEQUENCE DIQMTQTTSSLSASLGDRVTISCSASQDISSYLNWYQQKPEGTVKLLIYY >2HMI:D|PDBID|CHAIN|SEQUENCE QITLKESGPGIVQPSQPFRLTCTFSGFSLSTSGIGVTWIRQPSGKGLEWL >2HMI:E|PDBID|CHAIN|SEQUENCE ATGGCGCCCGAACAGGGAC >2HMI:F|PDBID|CHAIN|SEQUENCE GTCCCTGTTCGGGCGCCA""" # first, let's split the text il lines lines = text.split("\n") # then, let's create an empty dictionary sequence_of = {} # now we can iterate on lines for line in lines: if line[0] == ">": # if the line is a header, we extract the sequence name name = line.split("|")[0] else: # the line contains the sequence, that we add to the dictionary, using the name extracted before as key sequence_of[name] = line print sequence_of
Solutions:
Solution:
while raw_input("write 'STOP': ") != "STOP": print "you must write 'STOP'..."
Solution:
while raw_input("write stop: ").lower() != "stop": print "you must write 'stop'..."
Solutions:
- Solution: all numbers in
range(10)
. - Solution: the number
0
.break
immediately interrupts thefor
cycle. - Solution: all numbers in
range(10)
.continue
jumps to the next iteration, as Python automatically does when the instructions in thefor
cycle are finished. Sincecontinue
in this case is right at the end of thefor
cycle, it doesn’t have any effect. - Solution: the number
0
. In the first iteration, whennumber
has value0
, first Python executesprint number
, printing0
; thenif
is executed, and also thebreak
inside theif
, immediately interrupting thefor
cycle. - Solution: nothing. In the first iteration, when
number
has value0
,if
is executed and also thebreak
inside theif
, immediately interrupting thefor
cycle. Therefore,print
is never executed. - Solution: nothing. Instructions inside the
while
are never executed, since the condition isFalse
! - Solution: nothing. Instructions inside the
while
are never executed, since the condition isFalse
! As a consequence, the linecondition = True
is never executed. - Solution:
"the condition is true"
an infinite number of times. Since the condition is alwaysTrue
, thewhile
never stops iterating! - Solution: ten strings of the form
"position 0 contains the element 0"
,"position 1 contains the element 1"
, and so on - Solution: all the elements of
lines
(processed bystrip()
) occurring before the first empty line:"line 1"
,"line 2"
and"line 3"
. As soon asline
has value""
(the fourth element oflines
) theif
is executed, andbreak
interrupts the cycle. Note that the fourth row is not printed.
- Solution: all numbers in
Solution:
numbers = (0, 1, 1, 0, 0, 0, 1, 1, 2, 1, 2) for i in range(len(numbers)): number_in_pos_i = numbers[i] if number_in_pos_i == 2: print "the position is", i break
Solution:
strings = ("000", "51", "51", "32", "57", "26") for i in range(len(strings)): string_in_pos_i = strings[i] if "2" in string_in_pos_i: print "position =", i, "value =", string_in_pos_i break
Solution:
length = int(raw_input("write the length of the sequence: ")) import random alphabet = "AGCT" sequence = "" for i in range(length): index = random.randint(0, 3) sequence = sequence + alphabet[index] print sequence
Nested code¶
Solution:
n = 5 matrix = [range(n) for i in range(n)] for line in matrix: for element in line: print element
Solution:
- All the elements of the matrix.
- The sum of all the elements of the matrix.
- Again, all the elements of the matrix.
- Again, all the elements of the matrix.
- The list of the elements on the diagonal.
Solution:
numbers = [8, 3, 2, 9, 7, 1, 8] for num_1 in numbers: for num_2 in numbers: print num_1, num_2
This code is very similar to the clock example!
Solution:
numbers = [8, 3, 2, 9, 7, 1, 8] already_printed_pairs = [] for i in range(len(numbers)): for j in range(len(numbers)): pair = (numbers[i], numbers[j]) # check wheter we already printed the symmetric pair if (pair[1], pair[0]) in already_printed_pairs: continue # this code will be executed if the pair has not been printed: # print the pair and update already_printed_pairs print pair already_printed_pairs.append(pair)
The solution is the same of the previous exercise.
Solution:
numbers = range(10) for element_1 in numbers: for element_2 in numbers: if 2 * element_1 == element_2: print element_1, element_2
Solution:
numbers = [8, 3, 2, 9, 7, 1, 8] for element_1 in numbers: for element_2 in numbers: if element_1 + element_2 == 10: print element_1, element_2
Solution:
numbers = [8, 3, 2, 9, 7, 1, 8] # first, let's create an empty list list_of_pairs = [] for element_1 in numbers: for element_2 in numbers: if element_1 + element_2 == 10: # update the list with append() list_of_pairs.append((element_1, element_2)) # finally, let's print the list print list_of_pairs
Solution:
numbers_1 = [5, 9, 4, 4, 9, 2] numbers_2 = [7, 9, 6, 2] # iteration on the *first* list for i in range(len(numbers_1)): num_in_pos_i = numbers_1[i] # iteration on the *second* list for j in range(len(numbers_2)): num_in_pos_j = numbers_2[j] if num_in_pos_i == num_in_pos_j: print "positions:", i, j, "; repeated value:", num_in_pos_i
Solution:
numbers_1 = [5, 9, 4, 4, 9, 2] numbers_2 = [7, 9, 6, 2] # first, let's create an empty list list_of_triplets = [] # iteration on the *first* list for i in range(len(numbers_1)): num_in_pos_i = numbers_1[i] # iteration on the *second* list for j in range(len(numbers_2)): num_in_pos_j = numbers_2[j] if num_in_pos_i == num_in_pos_j: # instead of printing, we update the list llist_of_triplets.append((i, j, num_in_pos_i)) # finally, let's print the list print list_of_triplets
Solution:
n = 5 matrix = [range(n) for i in range(n)] # let's initialize with the first element (any other element would be fine as well) max_element_so_far = matrix[0][0] # iteration... for line in matrix: for element in line: # we update max_element_so_far when we find a higher element, if element > max_element_so_far: max_element_so_far = element print max_element_so_far
Solution:
sequences = [ "ATGGCGCCCGAACAGGGA", "GTCCCTGTTCGGGCGCCA", ] # first, let's create an empty list result = [] # iteration for sequence in sequences: # split the current sequence in triplets triplets = [] for i in range(0, len(sequence), 3): triplets.append(sequence[i:i+3]) # append (*not* extend()!!!) the obtained triplets # to the list result result.append(triplets) # finally, let's print the list print result
Solution:
numbers = [5, 9, 4, 4, 9, 2] num_occurrences = {} for number in numbers: if not num_occurrences.has_key(number): num_occurrences[number] = 1 else: num_occurrences[number] += 1
alternatively:
numbers = [5, 9, 4, 4, 9, 2] num_occurrences = {} for number in numbers: if not num_occurrences.has_key(number): num_occurrences[number] = 0 num_occurrences[number] += 1
or, using
count()
:numbers = [5, 9, 4, 4, 9, 2] num_occurrences = {} for number in numbers: if not num_occurrences.has_key(number): num_occurrences[number] = numbers.count(number)
Note that in the last variant, the
if
line is optional (but not the following “content”!)Solution:
groups = [["gene1", "gene2"], ["gene3"], [], ["gene4", "gene5"]] # let's initialize with the first group biggest_group_so_far = groups[0] # iteration for grup in groups[1:]: if len(gropu) > len(biggest_group_so_far): biggest_group_so_far = group print biggest_group_so_far
Solution:
sequences_2HMI = { "A": "PISPIETVPVKLKPGMDGPKVKQWPLTEEKI", "B": "PISPIETVPVKLKPGMDGPKVKQWPLTEEKI", "C": "DIQMTQTTSSLSASLGDRVTISCSASQDISS", "D": "QITLKESGPGIVQPSQPFRLTCTFSGFSLST", "E": "ATGGCGCCCGAACAGGGAC", "F": "GTCCCTGTTCGGGCGCCA", } # let's start with an empty dictionary histograms = {} for key, sequence in sequences_2HMI.items(): # let's associate this key to an empty dictionary histograms[key] = {} for residue in sequence: if not histograms[key].has_key(residue): histograms[key][residue] = 1 else: histograms[key][residue] += 1 # let's print the result print histograms # let's print the result more clearly for key, histogram in histograms.items(): print key print histogram print ""
Solution:
table = [ "protein domain start end", "YNL275W PF00955 236 498", "YHR065C SM00490 335 416", "YKL053C-A PF05254 5 72", "YOR349W PANTHER 353 414", ] # as before, first let's extract column names from the first row column_names = table[0].split() # let's start from an empty list lines_as_dictionaries = [] # now, let's iterate on the other rows for line in table[1:]: # let's compile the dictionary for this row dictionary = {} words = line.split() for i in range(len(words)): # extract the corresponding word word= words[i] # extract the corresponding column name column_name = column_names[i] # update the dictionary dictionary[column_name] = word # having compiled the dictionary for this line, # we can update the list lines_as_dictionaries.append(dictionary) # finished! now let's print the result (one row at a time, # to make it easier to read) for row in lines_as_dictionaries: print row
Solution:
alphabel_lo = "abcdefghijklmnopqrstuvwxyz" alphabet_up = alfabeto_min.upper() # let's build the dictionary lo_to_up = {} for i in range(len(alphabel_lo)): lo_to_up[alphabel_lo[i]] = alphabel_up[i] string = "I am a string" # let's convert the string converted_chars = [] for character in string: if lo_to_up.has_key(character): # convert the alphabetic character converted_chars.append(lo_to_up[character]) else: # we don't convert it (e.g., it's not an alphabetic character) converted_chars.append(character) converted_string = "".join(converted_chars) print converted_string
Solution:
lines_1 = open(raw_input("path 1: ")).readlines() lines_2 = open(raw_input("path 2: ")).readlines() # we have to be careful, since the two files could be of different lengths! max_lines = len(lines_1) if len(lines_2) > max_lines: max_lines = len(lines_2) # iteration on the lines of both files for i in range(max_lines): # take the i-th line of the first file, if existent, if i < len(lines_1): line_1 = lines_1[i].strip() else: line_1 = "" # take the i-th line of the second file, if existent, if i < len(lines_2): line_2 = lines_2[i].strip() else: line_2 = "" print line_1 + " " + line_2
Solution:
# let's read the fasta file fasta_as_dictionary = {} for line in open("data/dna-fasta/fasta.1").readlines(): # let's clean the sequence line = line.strip() if line[0] == ">": header = line fasta_as_dictionary[header] = "" else: fasta_as_dictionary[header] += line # let's iterate on header-sequence pairs for header, sequence in fasta_as_dictionary.items(): print "processind", header # let's count the number of occurrences of each nucleotide count = {} for nucleotide in ("A", "C", "G", "T"): count[nucleotide] = sequence.count(nucleotide) print "nucleotide occurrences:", count # calculate gc-content gc_content = (count["G"] + count["C"]) / float(len(sequence)) print "GC content:", gc_content # calculate the AT/GC-ratio sum_at = count["A"] + count["T"] sum_cg = count["C"] + count["G"] at_gc_ratio = float(sum_at) / float(sum_cg) print "AT/GC-ratio:", at_gc_ratio