Способ №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)
Задачки
Программа получает два файла: файл со счётчиками аминокислот и файл с последовательностью в FASTA формате. Программа считает количества аминокислот каждого типа во втором файле, добавляет их к значениями из первого файла, и записывает обратно в первый файл. Файл со счётчиками аминокислот дан в формате CSV, т.е. каждая строка состоит из пары буква запятая количество вхождений. – темы: файлы, словари
Программа получает на вход файл в формате FASTA. Файл содержит последовательности из разных банков данных. Первое слово в имени последовательности – её ID. Для последовательностей, взятых из uniprot, (uniprot id выглядит так: от 1 до 6 буквоцифр, далее символ '_', далее от 3 до 5 буквоцифр) сделать так, чтобы все слова в описании последовательности стали с заглавной буквы. – темы: файлы, строки, регулярные выражения
- Программа получает два числа из командной строки и пишет их сумму и произведение. Программа содержит две функции: add и multiply, которые реализуют ключевую функциональность программы. Данные функции должны сопровождаться самодокументацией и тестами.