Kodomo

Пользователь

Учебная страница курса биоинформатики,
год поступления 2010

Способ №1

   1 import re
   2 import optparse
   3 import doctest
   4 
   5 parser = optparse.OptionParser()
   6 parser.add_option("-i", "--input", help="Input filename")
   7 parser.add_option("-o", "--output", help="Output filename")
   8 options, args = parser.parse_args()
   9 
  10 def fragment_to_upper(sequence, start, stop):
  11   """Turn one part of sequence into uppercase letters.
  12 
  13   Example use:
  14   >>> fragment_to_upper("abcdefg", 1, 3)
  15   'aBCDefg'
  16   """
  17   return sequence[:start] + sequence[start:stop+1].upper() + sequence[stop+1:]
  18 
  19 fragments = []
  20 sequence = ""
  21 for line in open(options.input):
  22   line = line.strip()
  23   match = re.search(r"(\d+)[.][.](\d+)$", line)
  24   if match:
  25     start = int(match.group(1))
  26     stop = int(match.group(2))
  27     fragments.append([start, stop])
  28   else:
  29     sequence += line
  30 
  31 counts = {}
  32 sequence = sequence.lower()
  33 for start, stop in fragments:
  34   sequence = fragment_to_upper(sequence, start, stop)
  35   for c in sequence[start:stop+1]:
  36     if c in counts:
  37       counts[c] += 1
  38     else:
  39       counts[c] = 1
  40 
  41 outfile = open(options.output, 'w')
  42 outfile.write(str(counts) + "\n")
  43 outfile.write(sequence + "\n")
  44 
  45 doctest.testmod()

Способ №2

   1 import re
   2 import sys
   3 import doctest
   4 
   5 infile = open(sys.argv[1])
   6 outfile = open(sys.argv[2], 'w')
   7 
   8 def fragment_to_upper(sequence, start, stop):
   9   """Given a fragment of sequence (as list), turn it to uppercase. Return None
  10 
  11   Example:
  12   >>> sequence = ['a', 'b', 'c', 'd', 'e']
  13   >>> fragment_to_upper(sequence, 1, 3)
  14   >>> sequence
  15   ['a', 'B', 'C', 'D', 'e']
  16   """
  17   for i in range(start, stop + 1):
  18     sequence[i] = sequence[i].upper()
  19 
  20 body = infile.read()
  21 ranges = re.findall(r'(\d+)\.\.(\d+)', body)
  22 parts = re.findall(r'[A-Za-z]+', body)
  23 
  24 sequence = ""
  25 for part in parts:
  26   sequence += part.strip()
  27 sequence = sequence.lower()
  28 sequence = list(sequence)
  29 
  30 counts = {}
  31 for start, stop in ranges:
  32   start, stop = int(start), int(stop)
  33   fragment_to_upper(sequence, start, stop)
  34   for c in sequence[start:stop+1]:
  35     counts[c] = counts.get(c, 0) + 1
  36 
  37 sequence = "".join(sequence)
  38 outfile.write("Letter counts: {0}\n".format(counts))
  39 outfile.write("Sequence, with selected fragments uppercased\n{0}\n".format(sequence))
  40 
  41 doctest.testmod()

Способ №3, лучше двух других, но не покрывающий все нужные темы

   1 import sys
   2 import doctest
   3 
   4 def process_file(infile, outfile):
   5         """Count aminoacids and uppercase letters in selected regions.
   6 
   7         * `infile` contains specifications for regions and sequence.
   8         * write result to `outfile` 
   9         """
  10         ranges, sequence = parse_file(infile)
  11         counts = count_letter(sequence, ranges)
  12         sequence = sequence.lower()
  13         sequence = uppercase_regions(sequence, ranges)
  14         outfile.write("Aminoacid counts:\n{0}\n".format(format_counts(counts)))
  15         outfile.write("Sequence:\n{0}\n".format(sequence))
  16 
  17 def parse_file(infile):
  18         """Parse input file. Return specified ranges and sequence."""
  19         ranges = []
  20         sequence = ""
  21         for line in infile:
  22                 line = line.strip()
  23                 if '..' in line:
  24                         start, stop = line.split("..")
  25                         ranges.append((int(start), int(stop)+1)) # +1 allows python-style slices
  26                 else:
  27                         sequence += line
  28         return ranges, sequence
  29 
  30 def count_letters(sequence, ranges):
  31         """Count number of each letter occurences in given ranges of the sequence.
  32         
  33         Example:
  34         >>> counts = count_letters('aaaabbbb', [(3,4), (6,8)])
  35         >>> counts['a'], counts['b']
  36         1, 3
  37         """
  38         counts = {}
  39         for start, stop in ranges:
  40                 for c in sequence[start:stop]:
  41                         counts[c] = counts.get(c, 0) + 1
  42         return counts
  43 
  44 def uppercase_regions(sequence, ranges):
  45         """Return sequence with the given ranges uppercased.
  46 
  47         Example:
  48         >>> uppercase_regions('abcdefghijkl', [(1,2), (4,6)])
  49         'aBCdEFGhijkl'
  50         """
  51         for start, stop in ranges:
  52                 sequence = sequence[:start] + sequence[start:stop].upper() + sequence[stop:]
  53         return sequence
  54 
  55 def format_counts(counts):
  56         """Return a nicely-formatted string representation of letter counts dictionary.
  57         
  58         Example:
  59         >>> print format_counts({'z': 1, 'a': 5})
  60         a: 5
  61         z: 1
  62         """
  63         fragments = []
  64         for c in sorted(counts):
  65                 fragments.append("{0}: {1}".format(c, counts[c]))
  66         return "\n".join(fragments)
  67 
  68 if __name__ == "__main__":
  69         doctest.testmod()
  70         process_file(sys.stdin, sys.stdout)

Задачки