Вычисления не могут быть выполнены путем передачи значения из двух разных подпрограмм в новую подпрограмму: Perl

0

Я использовал анонимный хэш для передачи значения из двух разных подпрограмм в новую подпрограмму. Но теперь я не могу выполнять вычисления с использованием переданных переменных.

use warnings;
use strict;
use feature 'say';
use DBI;
use autodie;
use Data::Dumper;
use CGI;

print "Enter sequence";
my $seq = <STDIN>;
chomp $seq;
$len = length $seq;
my $f = nuc($seq);
perc({ len => $len });

sub nuc {
  my ($c) = @_;
  chomp $c;
  my $len = length $c;
  for (my $i = 0; $i< = $len; $i++) {
    my $seq2 = substr($c, $i, 1);
    $nuc=$nuc . $seq2;
    chomp $nuc; 
  }
  my $l = perc({nuc => $nuc});
} 

sub perc {
  my $params = shift;
  my $k = $params->{nuc};
  my $w = $params->{len};
  my $db = "hnf1a";
  my $user = "root";
  my $password = "";
  my $host = "localhost";
  my $dbh = DBI->connect("DBI:mysql:database=$db:$host",$user,$password);
  my $sth = $dbh->prepare('SELECT COUNT(*) FROM mody where nm = ?');
  for (1..100) {
    $sth->execute(int(rand(10)));
  }
  chomp (my $input = $k);
  my @num = split /':'/, $input;
  for my $num(@num)  {
    say "rows matching input nuc <$num>:";
    $sth->execute($num);
    my $count = $sth->fetchrow_array;
    say "$count";
    $u += $count;
  }
} 
$h = $u / $w;
print $h;

Я передал переменные: $ nuc и $ len до последней подпрограммы "perc", объявив анонимный хеш. Когда я использую эти переменные для выполнения вычислений, я не получаю правильный ответ. Для выполнения вышеуказанного деления я получил выражение как "Незаконное подразделение".

Пожалуйста, помогите мне. Заранее спасибо.

  • 4
    Пожалуйста, сделайте отступ в своем коде, чтобы он был читабельным. Спасибо
  • 0
    @Mojo: Я убрал форматирование вашего кода, чтобы было легче следить за ним. Пожалуйста, но, пожалуйста, сделайте это сами в будущем.
Теги:
database

2 ответа

3

Вы делаете два отдельных вызова perc, каждый из которых имеет только одно из требуемых значений в хэше. Вы не можете этого сделать: подпрограмма не "запомнит" значение, переданное ему через отдельные вызовы, если вы не напишете код для этого

Вам нужно собрать все значения и передать их за один вызов perc

  • 0
    Но мои переменные из разных подпрограмм? Как я могу передать его за один звонок?
0

Здесь довольно много недоразумений. Пропустите свой код.

use CGI;

Использование CGI.pm немного устарело, но это не ужасная идея, если вы пишете программу CGI. Но это не программа CGI, поэтому это необязательно.

print "Enter sequence";
my $seq = <STDIN>;
chomp $seq;
$len = length $seq;
my $f = nuc($seq);

Это выглядит нормально. Вы запрашиваете пользователя, получаете какой-то ввод, удаляете новую строку с конца ввода, получаете длину ввода и затем передаете свой вход в nuc().

Итак, давайте посмотрим на nuc() который, вероятно, может иметь лучшее имя!

sub nuc {
  my ($c) = @_;
  chomp $c;
  my $len = length $c;
  for (my $i = 0; $i< = $len; $i++) {
    my $seq2 = substr($c, $i, 1);
    $nuc=$nuc . $seq2;
    chomp $nuc; 
  }
  my $l = perc({nuc => $nuc});
}

Вы получаете параметр, который был передан, и удалите новую строку с конца (что ничего не делает, поскольку это $seq которого уже была удалена новая строка). Затем вы получите длину этой строки (снова!)

Тогда это становится очень странным. Во-первых, там синтаксическая ошибка (< = должна быть <=). Затем вы используете C-стиль для цикла вместе с substr() тоже... ну, в основном вы просто копируете $c в $nuc в действительно неэффективном порядке. Таким образом, эта подпрограмма может быть написана так:

sub nuc {
  my ($c) = @_;
  $nuc = $c;
  my $l = perc({ nuc => $nuc });
}

О, и я не знаю, почему вы chomp($nuc) каждый раз за цикл.

Еще две странные вещи. Во-первых, вы нигде не объявляете $nuc, и вы use strict в своем коде. Это означает, что этот код даже не компилируется. (Пожалуйста, не тратьте свое время на код, который не компилируется!) И, во-вторых, вы явно не возвращаете значение из nuc(), но сохраняете возвращаемое значение в $f. Из-за того, как работает Perl, эта подпрограмма вернет значение в $l. Но лучше всего быть явным.

Тогда есть ваша подпрограмма perc().

sub perc {
  my $params = shift;
  my $k = $params->{nuc};
  my $w = $params->{len};
  my $db = "hnf1a";
  my $user = "root";
  my $password = "";
  my $host = "localhost";
  my $dbh = DBI->connect("DBI:mysql:database=$db:$host",$user,$password);
  my $sth = $dbh->prepare('SELECT COUNT(*) FROM mody where nm = ?');
  for (1..100) {
    $sth->execute(int(rand(10)));
  }
  chomp (my $input = $k);
  my @num = split /':'/, $input;
  for my $num(@num)  {
    say "rows matching input nuc <$num>:";
    $sth->execute($num);
    my $count = $sth->fetchrow_array;
    say "$count";
    $u += $count;
  }
}

Вы получаете хэш-код, который передается в хранилище в $params. Затем вы извлекаете nuc и len значения из этого хэша и сохраняете их в переменных с именем $k и $w (вам действительно нужно улучшить свои имена переменных и подпрограмм!) Но каждый вызов perc имеет только одно из этих значений, поэтому только одна из двух переменных получает значение, другая - undef.

Итак, вы подключаетесь к базе данных. И вы запускаете запрос select, который сто раз передается в случайных целых числах от 0 до 9. И игнорируйте значение, возвращаемое из оператора select. Что странно и бессмысленно.

В конце концов, вы начинаете что-то делать с одним из ваших входных параметров, $k (другое, $w, полностью игнорируется). Вы копируете его в другую скалярную переменную, а затем разбиваете на массив. Затем вы запускаете один и тот же оператор SQL select для каждого элемента в этом массиве и добавляете число, которое вы возвращаете к текущей сумме в $u. И $u - это еще одна переменная, которую вы никогда не объявляете, поэтому (еще раз) этот код не компилируется.

Вне ваших подпрограмм вы затем выполняете простые математические вычисления с $u (необъявленная переменная) и $w (переменная, объявленная в другой области) и сохраняете результат в $h (другая необъявленная переменная).

Я действительно не понимаю, что должен делать этот код. И, честно говоря, я не думаю, что вы тоже. Если вы учитесь в школе, вам нужно вернуться к своему учителю и сказать, что вы не знаете, что делаете. Если вы работаете, вам нужно сообщить своему боссу, что вы не тот человек, который подходит к этой задаче.

В любом случае, если вы хотите быть программистом, вам нужно вернуться к началу и снова почистить самые основы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню