'n the chapter# fie insi%e the eer!ises %onoa%, theres a fie !ae% "na=t!t
hi!h !ontains a ma%e&p D;4 se<&en!e. #re%i!t the fragment engths that e i get if e %igest the se<&en!e ith to ma%e&p restri!tion enymes 5 4b!', hose re!ognition site is 4;$W44$, an% 4b!'', hose re!ognition site is RCW$R
1I ChapterH:eg&arepressions
&olutions
4ccession names
?bvio&sy, the b&- of the or- here is going to be !oming &p ith the reg&ar epression patterns to see!t ea!h s&bset of the a!!ession names. 7eres the easy bit 5 storing the a!!ession names in a ist an% then pro!essing them in a oop the first ine raps ro&n% be!a&se its too ong to fit on the page=:
accs B $*x:nJ'3G*, *yhdc:2*, *eihd3JdJ*, *chdsyeG'7*, *hedle3'*, *xDhd3e*, *'da*, *de37dp*
for acc in accs!
4 print if it passes the test
;o e !an ta!-e the %ifferent !riteria one by one. For ea!h eampe, the !o%e bor%ere% by soi% ines= is fooe% imme%iatey by the o&tp&t bor%ere% by %otte% ines=.
$he first !riterion is straightforar% 5 a!!essions that !ontain the n&mber . e %ont even have to &se any fan!y reg&ar epression feat&res:
for acc in accs!
if re.search(r**, acc#! print(*t* C acc# x:nJ'3G hedle3' xDhd3e 'da
;o for a!!essions that !ontain the etters % or e. e !an &se either aternation or a !hara!ter gro&p. 7eres a so&tion &sing aternation:
1@ ChapterH:eg&arepressions
for acc in accs!
if re.search(r*(dTe#*, acc#! print(*t* C acc# yhdc:2 eihd3JdJ chdsyeG'7 hedle3' xDhd3e 'da de37dp
$he net one 5 a!!essions that !ontain both the etters % an% e, in that or%er 5 is a bit more tri!-y. e !ant 9&st &se a simpe aternation or a !hara!ter gro&p, be!a&se they mat!h an* of their !onstit&ent parts, an% e nee% bot+ % an% e. ?ne ay to thin- of the pattern is %, fooe% by some other etters an% n&mbers, fooe% by e. e have to be !aref& ith o&r <&antifiers, hoever 5 at first gan!e the pattern
d.Fe oo-s goo%, b&t it i fai to mat!h the a!!ession here e foos % %ire!ty. $o ao for the fa!t that % might be imme%iatey fooe% by e, e nee% to &se the asteris-:
for acc in accs!
if re.search(r*d.Ke*, acc#! print(*t* C acc# chdsyeG'7 hedle3' xDhd3e de37dp
$he net re<&irement 5 %, fooe% by a singe etter, fooe% by e 5 is a!t&ay easier to rite a pattern for, even tho&gh it so&n%s more !ompi!ate%. e simpy remove the asteris-, an% the perio% i no mat!h any singe !hara!ter:
1G0 ChapterH:eg&arepressions
for acc in accs!
if re.search(r*(d.e#*, acc#! print(*t* C acc#
hedle3'
$he net re<&irement 5 % an% e in any or%er 5 is more %iffi!&t. e !o&% %o it ith an aternation &sing the pattern +d.4eJe.4d,, hi!h transates as " then e0 or e then " . 'n this !ase, ' thin- its !earer to !arry o&t to separate reg&ar epression sear!hes an% !ombine them into a !ompe !on%ition:
for acc in accs!
if re.search(r*d.Ke*, acc# or re.search(r*e.Kd*, acc#! print(*t* C acc#
hedle3' de37dp
$o fin% a!!essions that start ith either or y, e nee% to !ombine an aternation ith a startofstring an!hor:
for acc in accs!
if re.search(r*8(xTy#*, acc#! print(*t* C acc#
x:nJ'3G yhdc:2 xDhd3e
1G1 ChapterH:eg&arepressions
e !an mo%ify this <&ite easiy to a%% the re<&irement that the a!!ession en%s ith e. 4s before, e nee% to &se .W in the mi%%e to mat!h any n&mber of any
!hara!ter, res&ting in <&ite a !ompe pattern:
for acc in accs!
if re.search(r*8(xTy#.Ke6*, acc#! print(*t* C acc#
xDhd3e
$o mat!h three or more n&mbers in a ro, e nee% a more spe!ifi! <&antifier 5 the !&ry bra!-ets 5 an% a !hara!ter gro&p hi!h !ontains a the n&mbers:
for acc in accs!
if re.search(r*$0123'"7GJU3,100V*, acc#! print(*t* C acc#
x:nJ'3G chdsyeG'7 hedle3'
e !an a!t&ay ma-e this a bit more !on!ise. $he !hara!ter gro&p of a %igits is s&!h a !ommon one that theres a b&itin shorthan% for it: \d. e !an aso ta-e a%vantage of a shorthan% in the !&ry bra!-et <&antifier 5 if e eave off the &pper bo&n%, then it mat!hes ith no &pper imit. $he more !on!ise version:
for acc in accs!
if re.search(r*dU3,V*, acc#! print(*t* C acc#
1G2 ChapterH:eg&arepressions
x:nJ'3G chdsyeG'7 hedle3'
$he fina re<&irement is <&ite simpe an% ony re<&ires a !hara!ter gro&p an% an en%ofstring an!hor to sove:
for acc in accs!
if re.search(r*d$arp6*, acc#! print(*t* C acc#
'da de37dp
'ouble digest
$his is a har% probem, an% there are severa ays to approa!h it. +ets simpify it by first fig&ring o&t hat the fragment engths o&% be if e %igeste% the se<&en!e ith 9&st a singe restri!tion enyme1. e open an% rea% the fie a in one go
theres no nee% to pro!ess it inebyine as its 9&st a singe se<&en!e=, then e &se re.finditer to fig&re o&t the positions of a the !&t sites.
$he patterns themseves are reativey simpe: ; means any base, so the pattern for the 4b!' site is !!"#C2"!!". $he ambig&ity !o%e Q means ! or # an% the !o%e R means ! or ", so the pattern for 4b!'' is #C!#2!"2"#. 7eres the !o%e to
!a!&ate the start positions of the mat!hes for 4b!':
1 For the p&rposes of this eer!ise, e are of !o&rse ignoring a the interesting !hemi!a -ineti!s of restri!tion enymes an% ass&ming that a enymes !&t ith !ompete spe!ifi!ity an% effi!ien!y.
1G3 ChapterH:eg&arepressions
import re
dna B open(*dna.txt*#.read(#.rstrip(*n*# print(*A-cL cuts at!*#
for match in re.finditer(r*A$A)%&)AA)*, dna#! print(match.start(##
$he o&tp&t from this oo-s goo%:
A-cL cuts at! 11'0
1"2
b&t its not <&ite right 5 its teing &s the positions of the start of ea!h mat!h, b&t the enyme a!t&ay !&ts 3 base pairs &pstream of the start. $o get the position of the !&t site, e nee% to a%% three to the start of ea!h mat!h:
import re
dna B open(*dna.txt*#.read(#.rstrip(*n*# print(*A-cL cuts at!*#
for match in re.finditer(r*A$A)%&)AA)*, dna#! print(match.start(# C 3#
A-cL cuts at! 11'3
1"2G
;o eve got the !&t positions, ho are e going to or- o&t the fragment siesE ?ne ay is to go thro&gh ea!h !&t site in or%er an% meas&re the %istan!e beteen it an% the previo&s one 5 that i give &s the ength of a singe fragment. $o ma-e this or- e have to a%% >imaginary> !&t sites at the very start an% en% of the se<&en!e:
1GB ChapterH:eg&arepressions
import re
dna B open(*dna.txt*#.read(#.rstrip(*n*# all/cuts B $0
for match in re.finditer(r*A$A)%&)AA)*, dna#! all/cuts.append(match.start(# C 3#
all/cuts.append(len(dna## print(all/cuts#
+ets ta-e a moment to eamine hats going on in this program. e start by
!reating a ne ist variabe !ae% all_cuts to ho% the !&t positions ine 3=. 4t this point, the all_cuts variabe ony has one eement: ero, the position of the start of the se<&en!e. ;et, for ea!h mat!h to the pattern ine B=, e ta-e the start position, a%% three to it to get the !&t position, an% appen% that n&mber to the all_cuts ist ine =. Finay, e appen% the position of the ast !hara!ter in the D;4 string to the all_cuts ist ine G=. hen e print the all_cuts ist, e !an see that it !ontains the position of the start an% en% of the string, an% the interna positions of the !&t sites:
$0, 11'3, 1"2G, 2012
;o e !an rite a se!on% oop to go thro&gh the aY!&ts ist an%, for ea!h !&t position, or- o&t the sie of the fragment that i be !reate% by fig&ring o&t the %istan!e to the previo&s !&t site i.e. the previo&s eement in the ist=. $o ma-e this or-, hoever, e !ant 9&st &se a norma oop 5 e have to start at the se!on%
eement of the ist be!a&se the first eement has no previo&s eement= an% e have to or- ith the in%e of ea!h eement, rather than the eement itsef. e &se the range f&n!tion to generate the ist of in%ees that e ant to pro!ess 5 e nee% to go from in%e 1 i.e. the se!on% eement of the ist= to the ast in%e hi!h is the ength of the ist=:
1 2 3 4 5 6 7
1G ChapterH:eg&arepressions
for i in range(1,len(all/cuts##! this/cut/position B all/cuts$i
preious/cut/position B all/cuts$iF1
fragment/siEe B this/cut/position F preious/cut/position print(*one fragment siEe is * C str(fragment/siEe##
$he oop variabe i is &se% to store ea!h va&e that is generate% by the range f&n!tion ine 1=. For ea!h va&e of i e get the !&t position at that in%e ine 2= an% the !&t position at the previo&s in%e ine 3= an% then fig&re o&t the %istan!e beteen them ine B=. $he o&tp&t shos ho, for to !&ts, e get three
fragments:
one fragment siEe is 11'3 one fragment siEe is 'G one fragment siEe is 3G'
;o for the fina part of the so&tion: ho %o e %o the same thing for to
%ifferent enymesE e !an a%% in the se!on% enyme pattern ith the appropriate !&t site offset an% appen% the !&t positions to the all_cuts variabe:
import re
dna B open(*dna.txt*#.read(#.rstrip(*n*# all/cuts B $0
4 add cut positions for A-cL
for match in re.finditer(r*A$A)%&)AA)*, dna#! all/cuts.append(match.start(# C 3#
4 add cut positions for A-cLL
for match in re.finditer(r*%&$A%$A))%*, dna#! all/cuts.append(match.start(# C '#
4 add the final position all/cuts.append(len(dna## print(all/cuts# 1 2 3 4 5
1GG ChapterH:eg&arepressions
b&t oo- hat happens hen e print the eements of aY!&ts:
$0, 11'3, 1"2G, 'GG, 177, 2012
e get ero, then the to !&t positions for the first enyme in as!en%ing or%er, then the to !&t positions for the se!on% enyme in as!en%ing or%er, then the position of the en% of the se<&en!e. $he metho% for t&rning a ist of !&t positions into fragment sies that e %eveope% above isnt going to or- ith this ist,
be!a&se it reies on the ist of positions being in as!en%ing or%er. 'f e try it ith the ist of !&t positions pro%&!e% by the above !o%e, e en% &p ith obvio&sy in!orre!t fragment sies:
one fragment siEe is 11'3 one fragment siEe is 'G one fragment siEe is F11'0 one fragment siEe is 10GJ one fragment siEe is '3'
7appiy, #ythons b&itin sort f&n!tion !an !ome to the res!&e. 4 e nee% to %o is sort the ist of !&t positions before pro!essing it, an% e get the right ansers. 7eres the !ompete, fina !o%e:
1GH ChapterH:eg&arepressions
import re
dna B open(*dna.txt*#.read(#.rstrip(*n*# print(str(len(dna###
all/cuts B $0
4 add cut positions for A-cL
for match in re.finditer(r*A$A)%&)AA)*, dna#! all/cuts.append(match.start(# C 3#
4 add cut positions for A-cLL
for match in re.finditer(r*%&$A%$A))%*, dna#! all/cuts.append(match.start(# C '#
4 add the final position all/cuts.append(len(dna## sorted/cuts B sorted(all/cuts# print(sorted/cuts# for i in range(1,len(sorted/cuts##! this/cut/position B sorted/cuts$i preious/cut/position B sorted/cuts$iF1
fragment/siEe B this/cut/position F preious/cut/position print(*one fragment siEe is * C str(fragment/siEe##
1GI ChapterI:Di!tionaries
8:
'ictionaries
&toring paire" "ata
"&ppose e ant to !o&nt the n&mber of 4s in a D;4 se<&en!e. Carrying o&t the !a!&ation is <&ite straightforar% 5 in fa!t its one of the first things e %i% in !hapter 2:
dna B *A)&%A)&%A)&%)A&%&)%A* a/count B dna.count(*A*#
7o i o&r !o%e !hange if e ant to generate a !ompete ist of base !o&nts for the se<&en!eE e a%% a ne variabe for ea!h base:
dna B *A)&%A)&%A)&%)A&%&)%A* a/count B dna.count(*A*#
t/count B dna.count(*)*# g/count B dna.count(*%*# c/count B dna.count(*&*#
an% no o&r !o%e is starting to oo- rather repetitive. 'ts not too ba% for the fo&r in%ivi%&a bases, b&t hat if e ant to generate !o&nts for the 1G %in&!eoti%es:
dna B *A)&%A)&%A)&%)A&%&)%A* aa/count B dna.count(*AA*# at/count B dna.count(*A)*# ag/count B dna.count(*A%*# ...etc. etc. or the GB trin&!eoti%es:
1G@ ChapterI:Di!tionaries dna B *A)&%A)&%A)&%)A&%&)%A* aaa/count B dna.count(*AAA*# aat/count B dna.count(*AA)*# aag/count B dna.count(*AA%*# ...etc. etc.
For trin&!eoti%es an% onger, the sit&ation is parti!&ary ba%. $he D;4 se<&en!e is 20 bases ong, so it ony !ontains 1I overapping trin&!eoti%es in tota. $his means that e en% &p ith GB %ifferent variabes, at east BG of hi!h i ho% the va&e ero.
?ne possibe ay ro&n% this is to store the va&es in a ist. 'f e &se three neste% oops, e !an generate a possibe trin&!eoti%es, !a!&ate the !o&nt for ea!h one, an% store a the !o&nts in a ist:
dna B *AA)%A)&%A)&%)A&%&)%A* all/counts B $
for -ase1 in $A, ), %, &! for -ase2 in $A, ), %, &!
for -ase3 in $A, ), %, &!
trinucleotide B -ase1 C -ase2 C -ase3 count B dna.count(trinucleotide#
print(*count is * C str(count# C * for * C trinucleotide# all/counts.append(count#
1H0 ChapterI:Di!tionaries
4tho&gh the !o%e is above is <&ite !ompa!t, an% %oesnt re<&ire h&ge n&mbers of variabes, the o&tp&t shos to probems ith this approa!h:
count is 0 for AAA count is 1 for AA) count is 0 for AA% count is 0 for AA& count is 0 for A)A count is 0 for A)) count is 1 for A)% count is 2 for A)&
W many lines remoed W
$0, 1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0
Firsty, the %ata are sti in!re%iby sparse 5 the vast ma9ority of the !o&nts are ero. "e!on%y, the !o&nts themseves are no %is!onne!te% from the trin&!eoti%es. 'f e ant to oo- &p the !o&nt for a singe trin&!eoti%e 5 for eampe, $R4 5 e
first have to fig&re o&t that $R4 as the 2th trin&!eoti%e generate% by o&r oops. ?ny then !an e get the eement at the !orre!t in%e:
1H1 ChapterI:Di!tionaries
e !an try vario&s tri!-s to get ro&n% this probem. hat if e generate% to ists 5 one of !o&nts, an% one of the trin&!eoti%es themsevesE
dna B *AA)%A)&%A)&%)A&%&)%A* all/trinucleotides B $
all/counts B $
for -ase1 in $A, ), %, &! for -ase2 in $A, ), %, &!
for -ase3 in $A, ), %, &!
trinucleotide B -ase1 C -ase2 C -ase3 count B dna.count(trinucleotide#
all/trinucleotides.append(trinucleotide# all/counts.append(count#
print(all/counts#
print(all/trinucleotides#
;o e have to ists of the same ength, ith a onetoone !orrespon%en!e beteen the eements:
$0, 1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0
$AAA, AA), AA%, AA&, A)A, A)), A)%, A)&, A%A, A%), A%%, A%&, A&A, A&), A&%, A&&, )AA, )A), )A%, )A&, ))A, ))), ))%, ))&, )%A, )%), )%%, )%&, )&A, )&), )&%, )&&, %AA, %A), %A%, %A&, %)A, %)), %)%, %)&, %%A, %%), %%%, %%&, %&A, %&), %&%, %&&, &AA, &A), &A%, &A&, &)A, &)), &)%, &)&, &%A, &%), &%%, &%&, &&A, &&), &&%, &&&
$his aos &s to oo- &p the !o&nt for a given trin&!eoti%e in a sighty more appeaing ay 5 e !an oo- &p the in%e of the trin&!eoti%e in the
all_trinucleotides ist, then get the !o&nt at the same in%e in the all_counts ist:
1H2 ChapterI:Di!tionaries
i B all/trinucleotides.index()%A# c B all/counts$i
print(count for )%A is C str(c##
$his is a itte bit ni!er, b&t sti has ma9or %raba!-s. ere sti storing a those eros, an% no e have to ists to -eep tra!- of. e nee% to be in!re%iby !aref& hen manip&ating either of the to ists to ma-e s&re that they stay perfe!ty
syn!hronie% 5 if e ma-e any !hange to one ist b&t not the other, then there i no onger be a onetoone !orrespon%en!e beteen eements an% e get the rong anser hen e try to oo- &p a !o&nt.
$his approa!h is aso so 1. $o fin% the in%e of a given trin&!eoti%e in the
all_trinucleotides ist, #ython has to oo- at ea!h eement one at a time &nti it fin%s the one ere oo-ing for. $his means that as the sie of the ist gros 2, the time ta-en to oo- &p the !o&nt for a given eement i gro aongsi%e it.
'f e ta-e a step ba!- an% thin- abo&t the probem in more genera terms, hat e nee% is a ay of storing pairs of %ata in this !ase, trin&!eoti%es an% their !o&nts= in a ay that aos &s to effi!ienty oo- &p the !o&nt for any given trin&!eoti%e. $his probem of storing paire% %ata is in!re%iby !ommon in programming. e might ant to store:
• protein se<&en!e names an% their se<&en!es • D;4 restri!tion enyme names an% their motifs • !o%ons an% their asso!iate% amino a!i% resi%&es • !oeag&es names an% their emai a%%resses • sampe names an% their !oor%inates
• or%s an% their %efinitions
1 4s a r&e, eve avoi%e% ta-ing abo&t performan!e in this boo-, b&t e brea- the r&e in this !ase. 2 For instan!e, imagine !arrying o&t the same eer!ise ith the approimatey one miion &ni<&e 10mers.
1H3 ChapterI:Di!tionaries
4 these are eampes of hat e !a keyBvalue pairs. 'n ea!h !ase e have pairs of keys an% values:
<e* =alue
trin&!eoti%e !o&nt
name protein se<&en!e
name restri!tion enyme motif !o%on amino a!i% resi%&e
name emai a%%ress sampe !oor%inates
or% %efinition
$he ast eampe in this tabe 5 or%s an% their %efinitions 5 is an interesting one