Я учусь на вводном курсе Perl и ищу предложения и отзывы о моем подходе к написанию небольшой (но хитрой) программы, которая анализирует данные об атомах.Мой профессор поощряет форумы.Я не знаком с сабвуферами или модулями Perl (включая Bioperl), поэтому, пожалуйста, ограничьте ответы соответствующим «начальным уровнем», чтобы я мог понять и извлечь уроки из ваших предложений и / или кода (также ограничьте «Магию», пожалуйста).
Требования программы следующие:
Считать файл (содержащий данные об атомах) из командной строки и создать массив записей атомов(одна запись / атом на новую строку).Для каждой записи программе необходимо хранить:
• Серийный номер атома (столбцы 7 - 11)
• Трехбуквенное название аминокислоты, к которой он принадлежит (столбец 18- 20)
• Три координаты атома (x, y, z) (столбцы 31 - 54)
• Имя элемента из одной или двух букв (например, C, O, N, Na) (столбцы77-78)
Запрашивать одну из трех команд: частота, длина, плотность d (d - некоторое число):
• частота- сколько атомов каждого типа содержится в файле (например, азот, натрий и т. д. будут отображаться так: N: 918 S: 23
• длина - расстояния между координатами
• плотность d (где dявляется числом) - программа запросит имя файла для сохранения вычислений и будет содержать расстояние между этим атомом и каждым другим атомом. Если это расстояние меньше или равно числу d, оно увеличивает счетчикчисло атомов, которые находятся в пределах этого расстояния, если только это число не равно нулюo файл. Вывод будет выглядеть примерно так:
1: 5
2: 3
3: 6
... (очень большой файл) и закроется после его завершения.
Я ищу отзывы о том, что я написал (и должен написать) в приведенном ниже коде.Я особенно ценю любые отзывы о том, как подойти к написанию моих сабов.Я включил пример входных данных внизу.
Структура программы и описания функций, как я ее вижу:
$^W = 1; # turn on warnings
use strict; # behave!
my @fields;
my @recs;
while ( <DATA> ) {
chomp;
@fields = split(/\s+/);
push @recs, makeRecord(@fields);
}
for (my $i = 0; $i < @recs; $i++) {
printRec( $recs[$i] );
}
my %command_table = (
freq => \&freq,
length => \&length,
density => \&density,
help => \&help,
quit => \&quit
);
print "Enter a command: ";
while ( <STDIN> ) {
chomp;
my @line = split( /\s+/);
my $command = shift @line;
if ($command !~ /^freq$|^density$|length|^help$|^quit$/ ) {
print "Command must be: freq, length, density or quit\n";
}
else {
$command_table{$command}->();
}
print "Enter a command: ";
}
sub makeRecord
# Read the entire line and make records from the lines that contain the
# word ATOM or HETATM in the first column. Not sure how to do this:
{
my %record =
(
serialnumber => shift,
aminoacid => shift,
coordinates => shift,
element => [ @_ ]
);
return\%record;
}
sub freq
# take an array of atom records, return a hash whose keys are
# distinct atom names and whose values are the frequences of
# these atoms in the array.
sub length
# take an array of atom records and return the max distance
# between all pairs of atoms in that array. My instructor
# advised this would be constructed as a for loop inside a for loop.
sub density
# take an array of atom records and a number d and will return a
# hash whose keys are atom serial numbers and whose values are
# the number of atoms within that distance from the atom with that
# serial number.
sub help
{
print "To use this program, type either\n",
"freq\n",
"length\n",
"density followed by a number, d,\n",
"help\n",
"quit\n";
}
sub quit
{
exit 0;
}
# truncating for testing purposes. Actual data is aprox. 100 columns
# and starts with ATOM or HETATM.
__DATA__
ATOM 4743 CG GLN A 704 19.896 32.017 54.717 1.00 66.44 C
ATOM 4744 CD GLN A 704 19.589 30.757 55.525 1.00 73.28 C
ATOM 4745 OE1 GLN A 704 18.801 29.892 55.098 1.00 75.91 O