<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 <H1>PrimerDesign</H1>
We need to define a sequence of 17 bases with the following requirements
Step1:  The function product is what we need to obtain a sequence of x elements with the four nucleotides A, G, C and T. This will give us $4^{x}$. To compute the product of an iterable with itself, specify the lenght of the sequence with the optional repeat keyword argument. For example,
product(A, repeat=4) means the same as product(A, A, A, A) will be taken.
Step2:  In the first and last 5 bases, we need zero, one or two G or C
Step3:  <H2> Generate sequences with around 50% of GC</H2>
We will insert about 50% of GC content in a 17 pairbase sequence. For that, we will fill the sequence with 9 nucleotides containing either G or C. This with first give us 2^9 sequence combinations.
Step5:  For every GC sequence, we will add a AT sequence with the same combinatorial procedure
Step7:  we will apply now more restrictions to the sequences
<H2>GC Clamp</H2>
This is the number of G or C in the last 5 bases of the sequence
Step9:  Count all the posibilities  with score less than 10
<ASSISTANT_TASK:>
Python Code:
%pylab inline
from itertools import product, permutations
from math import pow
Explanation: <H1>PrimerDesign</H1>
We need to define a sequence of 17 bases with the following requirements:
<ul>
    <li>Total GC content: 40-60%</li>
    <li>GC Clamp: < 3 in the last 5 bases at the 3' end of the primer.</li>
</ul>
End of explanation
pow(4,17) # all possible ATGC combinations in sequences of 17 bases
pow(4,7) # all possible ATCG combinations in sequences of 7 elements
pow(4,5) # all possible ATCG combinations in sequences of 5 elements
Explanation: The function product is what we need to obtain a sequence of x elements with the four nucleotides A, G, C and T. This will give us $4^{x}$. To compute the product of an iterable with itself, specify the lenght of the sequence with the optional repeat keyword argument. For example,
product(A, repeat=4) means the same as product(A, A, A, A) will be taken.
End of explanation
perms = [''.join(p) for p in permutations('ATCG')]
perms
pow(2,5) # only AT combinations in 5 elements
print list(permutations(['A','T'], 'C'))
pow(2,5)+ 5*pow(2,4) + 5*pow(2,4) + 
mySeq = Seq
x = [i for i in list(product('GCAT', repeat=7))]
x[0]
x = [i for i in list(product('GCAT'), repeat)]
mybase = ('A', 'T', 'C','G')
product('ATCG',2)
from Bio.Seq import Seq # Biopython
from Bio.SeqUtils import GC
from Bio import pairwise2
from Bio.pairwise2 import format_alignment
mySeq = Seq('ATCG')
GC(mySeq) # returns % of GC content
mySeq
Explanation: In the first and last 5 bases, we need zero, one or two G or C
End of explanation
# this is the number of all possible C or G combinations in a sequence of 8 elements.
pow(2,9) 
Explanation: <H2> Generate sequences with around 50% of GC</H2>
We will insert about 50% of GC content in a 17 pairbase sequence. For that, we will fill the sequence with 9 nucleotides containing either G or C. This with first give us 2^9 sequence combinations.
End of explanation
256*512
# example of joining list
myGC = [''.join(i) for i in list(product('GC', repeat=9))] # 512 sequences
myAT = [''.join(j) for j in list(product('AT', repeat=8))] # 256 sequences
print(myGC[0],myAT[0])
zip(myGC[0],myAT[0])
mystring = str()
for i,j in zip(myGC[0],myAT[100]):
    mystring +=i+j
    
mystring
def generateSeq(listGC, listAT):
    
    Create all possible combinations of the sequences in 
    list GC and listAT. The only requirement is that
    the 
    
    Arguments:
    ==========
    
    listGC -- a list of strings containing GC nucleotides
    listAT -- a list of strings containing AT nucleotides
    
    Returns
    =======
    
    A list of Seq objects
    
    
    mySeqList = list()
    for list1 in listGC:
        for list2 in listAT:
            mystring = str()
            for i,j in zip(list1, list2):
                mystring += i+j
            mystring +=list1[-1]# add last element from listGC
            mySeqList.append(Seq(mystring))
                
    return mySeqList
        
generateSeq(myGC[:3],myAT[:3]) #dummy test
mySeq = generateSeq(myGC,myAT)
len(mySeq)
Explanation: For every GC sequence, we will add a AT sequence with the same combinatorial procedure
End of explanation
def GCClamp(seq):
    
    returns the number of G or C within the last five bases of the sequence
    
    return seq[-5:].count('G') + seq[-5:].count('C')
mySeq[0]
GCClamp(mySeq[0])
GC
# count the number of sequences GC Clamp below three
[seq for seq in mySeq if GCClamp(seq)]
mySeq[0][-5:].count('G')
'G' in mySeq[0][-5:]
mySeq[0][-5:]
print 'original   = ' + mySeq[100000]
print 'complement = ' + mySeq[100000].complement()
alignments = pairwise2.align.globalxx(mySeq[100000], mySeq[100000])
alignments
%timeit 
for a in pairwise2.align.globalxx(mySeq[100000].complement(), mySeq[100000].complement()):
    print(format_alignment(*a))
    al1,al2, score, begin, end = a
    print score
Explanation: we will apply now more restrictions to the sequences
<H2>GC Clamp</H2>
This is the number of G or C in the last 5 bases of the sequence
End of explanation
def countScores(seqList, threshold=None):
    
    Counts the number of sequences whose complementary gives
    similarty less than
    the threshold given as a argument.
    
    Argument:
    =========
    
    seqList -- list, this is a list of Seq objects
    threshod -- int, the number of complementary bases that binds
    
    Returns:
    ========
    
    A interger with the number of sequencies that fullfit that requirement
    
    #generate complement list
    compSeq = [i.complement() for i in seqList]
    
    counter = 0
    for seq in seqList:
        average = list()
        for comp in compSeq:
            a = pairwise2.align.globalxx(seq, comp)
            average.append(a[0][2]) # append score
        if np.mean(average)<threshold:
            counter +=1
        
    return counter 
countScores(mySeq[:3], threshold=10) # test for a list of three seq three
countScores(mySeq, threshold=10)
for a in pairwise2.align.globalxx(mySeq[0], mySeq[0].complement()):
    print(format_alignment(*a))
    al1,al2, score, begin, end = a
    print score
alignments = pairwise2.align.globalxx("ACCGT", "ACG")
for a in pairwise2.align.globalxx("ACCGT", "ACG"):
    print(format_alignment(*a))
print(mylist[0])
print(mylist[1])
for a in pairwise2.align.globalxx(mylist[0], mylist[1]):
    print(format_alignment(*a))
myseq = 'ATCG'
print list(product(myseq, repeat=2))
256*256
Explanation: Count all the posibilities  with score less than 10
End of explanation
<END_TASK>