Control_Flow_Statements.rst 6.95 KB
Newer Older
1
2
3
.. sectnum::
   :start: 7

Bertrand  NÉRON's avatar
Bertrand NÉRON committed
4
5
6
7
8
9
.. _Control_Flow_Statements:


***********************
Control Flow Statements
***********************
10

11
12
Exercises
=========
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

Exercise
--------

The Fibonacci sequence are the numbers in the following integer sequence:

    0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...

By definition, the first two numbers in the Fibonacci sequence are 0 and 1, 
and each subsequent number is the sum of the previous two.
The fibonacci suite can be defined as following:

|    F\ :sub:`0` = 0, F\ :sub:`1` = 1. 
|    
|    F\ :sub:`n` = F\ :sub:`n-1` + F\ :sub:`n-2` 

29
30
31
32
Write a function which take an integer ``n`` as parameter
and returns a list containing the ``n`` first number of the Fibonacci sequence. 


33
34
35
36
.. literalinclude:: _static/code/fibonacci_iteration.py
   :linenos:
   :language: python
   
37
:download:`fibonacci_iteration.py <_static/code/fibonacci_iteration.py>` .
Bertrand  NÉRON's avatar
Bertrand NÉRON committed
38
We will see another way more elegant to implement the fibonacci suite in :ref:`Advanced Programming Techniques` section.
39

40
41


Bertrand  NÉRON's avatar
Bertrand NÉRON committed
42
43
44
Exercise
--------

45
46
47
Reimplement your own function max (my_max).
This function will take a list or tuple of float or integer and 
returns the largest element?
48

49
50
51
52
53
54
55
56
57
58
59
Write the pseudocode before to propose an implementation.

pseudocode
^^^^^^^^^^

| *function my_max(l)*
|   *max <- first elt of l*
|   *for each elts of l*
|       *if elt is > max*
|       *max <- elt*
|   *return max*
60

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

implementation
^^^^^^^^^^^^^^

::

   def my_max(seq):
      """
      return the maximum value in a sequence 
      work only with integer or float
      """
      higest = seq[0]
      for i in seq:
         if i > highest:
             highest = i
      return highest
      
   l = [1,2,3,4,58,9]
   print my_max(l)
   58
   
Bertrand Néron's avatar
Bertrand Néron committed
82
83
84

.. _enzyme_exercise:

85
86
87
Exercise
--------

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
| We want to establish a restriction map of a sequence. 
| But we will do this step by step.
| and reuse the enzymes used in previous chapter: 

* create a function that take a sequence and an enzyme as parameter and return 
   the position of first binding sites.
   (write the pseudocode)

**pseudocode** 
   
| *function one_enz_binding_site(dna, enzyme)*
|     *if enzyme binding site is substring of dna*
|          *return of first position of substring in dna* 
 
**implementation**
 
.. literalinclude:: _static/code/restriction.py
   :linenos:
106
   :lines: 1-14
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
   :language: python
   
* improve the previous function to return all positions of binding sites

**pseudocode of first algorithm**

| *function one_enz_binding_sites(dna, enzyme)*
|     *positions <- empty*
|     *if enzyme binding site is substring of dna*
|          *add the position of the first substring in dna in positions* 
|     *positions <- find binding_sites in rest of dna sequence*
|     *return positions*  

**implementation**

.. literalinclude:: _static/code/restriction.py
   :linenos:
124
   :lines: 15-31
125
126
127
128
   :language: python

**pseudocode of second algorithm**

129
| *function one_enz_all_binding_sites_2(dna, enzyme)*
130
131
132
133
134
135
136
137
138
139
140
|     *positions <- empty*
|     *find first position of binding site in dna*
|     *while we find binding site in dna*
|         *add position of binding site to positions*
|         *find first position of binding site in dna in rest of dna*
|     *return positions*

**implementation**

.. literalinclude:: _static/code/restriction.py
   :linenos:
141
   :lines: 32-53
142
143
144
145
146
147
   :language: python
   
   
search all positions of Ecor1 binding sites in dna_1

::
148
149
150
151
152
 
   import collections
   RestrictEnzyme = collections.namedtuple("RestrictEnzyme", "name comment sequence cut end")

   ecor1 = RestrictEnzyme("EcoRI", "Ecoli restriction enzime I", "gaattc", 1, "sticky")
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
   
   dna_1 = """tcgcgcaacgtcgcctacatctcaagattcagcgccgagatccccgggggttgagcgatccccgtcagttggcgtgaattcag
   cagcagcgcaccccgggcgtagaattccagttgcagataatagctgatttagttaacttggatcacagaagcttccaga
   ccaccgtatggatcccaacgcactgttacggatccaattcgtacgtttggggtgatttgattcccgctgcctgccagg"""
   
   
* generalize the binding sites function to take a list of enzymes and return a list of tuple (enzyme name, position) 
   
**pseudocode**

| *function binding_sites(dna, set of enzymes)*
|     *positions <- empty*
|     *for each enzyme in enzymes*
|         *pos <- one_enz_binding_sites(dna, enzyme)*
|         *pos <- for each position create a tuple enzyme name, position*
|         *positions <- pos*
|     *return positions*

**implementation**

in bonus we can try to sort the list in the order of the position of the binding sites like this:
[('Sau3aI', 38), ('SmaI', 42), ('Sau3aI', 56), ('EcoRI', 75), ...

.. literalinclude:: _static/code/restriction.py
   :linenos:
178
   :lines: 54-
179
180
181
182
183
184
185
186
   :language: python
   
::
 
   import collections
   RestrictEnzyme = collections.namedtuple("RestrictEnzyme", "name comment sequence cut end")

   ecor1 = RestrictEnzyme("EcoRI", "Ecoli restriction enzime I", "gaattc", 1, "sticky")   
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
   ecor5 = RestrictEnzyme("EcoRV", "Ecoli restriction enzime V", "gatatc", 3, "blunt")
   bamh1 = RestrictEnzyme("BamHI", "type II restriction endonuclease from Bacillus amyloliquefaciens ", "ggatcc", 1, "sticky")
   hind3 = RestrictEnzyme("HindIII", "type II site-specific nuclease from Haemophilus influenzae", "aagctt", 1 , "sticky")
   taq1 = RestrictEnzyme("TaqI", "Thermus aquaticus", "tcga", 1 , "sticky")
   not1 = RestrictEnzyme("NotI", "Nocardia otitidis", "gcggccgc", 2 , "sticky")
   sau3a1 = RestrictEnzyme("Sau3aI", "Staphylococcus aureus", "gatc", 0 , "sticky")
   hae3 = RestrictEnzyme("HaeIII", "Haemophilus aegyptius", "ggcc", 2 , "blunt")
   sma1 =  RestrictEnzyme("SmaI", "Serratia marcescens", "cccggg", 3 , "blunt")

and the 2 dna fragments: ::

   dna_1 = """tcgcgcaacgtcgcctacatctcaagattcagcgccgagatccccgggggttgagcgatccccgtcagttggcgtgaattcag
   cagcagcgcaccccgggcgtagaattccagttgcagataatagctgatttagttaacttggatcacagaagcttccaga
   ccaccgtatggatcccaacgcactgttacggatccaattcgtacgtttggggtgatttgattcccgctgcctgccagg"""

   dna_2 = """gagcatgagcggaattctgcatagcgcaagaatgcggccgcttagagcgatgctgccctaaactctatgcagcgggcgtgagg
   attcagtggcttcagaattcctcccgggagaagctgaatagtgaaacgattgaggtgttgtggtgaaccgagtaag
   agcagcttaaatcggagagaattccatttactggccagggtaagagttttggtaaatatatagtgatatctggcttg"""

206
207
208
209
   enzymes= (ecor1, ecor5, bamh1, hind3, taq1, not1, sau3a1, hae3, sma1)
   binding_sites(dna_1, enzymes)
   [('Sau3aI', 38), ('SmaI', 42), ('Sau3aI', 56), ('EcoRI', 75), ('SmaI', 95), ('EcoRI', 105), 
   ('Sau3aI', 144), ('HindIII', 152), ('BamHI', 173), ('Sau3aI', 174), ('BamHI', 193), ('Sau3aI', 194)]
210

211
212
213
   binding_sites(dna_2, enzymes)
   [('EcoRI', 11), ('NotI', 33), ('HaeIII', 35), ('EcoRI', 98), ('SmaI', 106), 
   ('EcoRI', 179), ('HaeIII', 193), ('EcoRV', 225)]
214
   
215
:download:`restriction.py <_static/code/restriction.py>` .
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

Exercise
--------

From a list return a new list without any duplicate, but keeping the order of items. 
For example: ::

   >>> l = [5,2,3,2,2,3,5,1]
   >>> uniqify_with_order(l)
   >>> [5,2,3,1]  

solution ::

   >>> uniq = []
   >>> for item in l:
   >>>   if item not in uniq:
   >>>      uniq.append(item)

solution ::

   >>> uniq_items = set()
   >>> l_uniq = [x for x in l if x not in uniq_items and not uniq_items.add(x)]
     
240