Perl index function to extract a certain substring - perl

Given a certain sequence A stored in an array, I have to find if a larger sequence B contains sequence A.
I am stuck at the index part... and i'm getting an error that argument "TGACCA" isn't numeric in array element in line 69 which is:
if (index($record_r1[1], $r2_seq[$check]) != -1)
The code is:
foreach my $check (#r2_seq)
{
if (index($record_r1[1], $r2_seq[$check]) != -1)
{
$matches= $matches + 1;
print "Matched";
}
else
{
}
}

foreach my $check (#r2_seq)
$check takes on the value of each element in #r2_seq. It is not the index.
$r2_seq[$check]
This is attempting to use an element of #r2_seq as the index into #r2_seq. It is unlikely what you want. More probably, you want to use
$check
as in
if (index($record_r1[1], $check) != -1)
.

I believe you wanted $check to be index, so then use the following code:
foreach my $index (0..$#r2_seq)
{
if (index($record_r1[1], $r2_seq[$index]) != -1)
{
$matches= $matches + 1;
print "Matched";
}
else
{
}
}

Related

How to split string by comma into a hash in Perl?

I have the following code:
my #logs = split(",",$opts->{"logs"});
$opt_href->{"logs"} = \#logs;
It basically splits the $opts->{"logs"} by comma and keeps the array ref. Later I need to check if string exists in the $opt_href->{"logs"} array. Looking at this topic, I see that it's recommended to keep a hash, instead of array. I could just do:
my %logs;
for each my $log (split(",",$opts->{"logs"})) {
$logs{$log} = 1;
}
$opt_href->{"logs"} = \%logs;
Is there a better way to do this? Maybe a one/two liners?
my %logs = map { $_ => 1 } split /,/, $opts->{logs};
$opt_href->{logs} = \%logs;
Or, using the anonymous hash reference, constructed by { }
$opt_href->{logs} = { map { $_ => 1 } split /,/, $opts->{logs} };

How to cast a column when using $this->db->like?

In my application there is a dataTable , so there is the search mechanism , and one of the columns in the dataTable has an int datatype. Here is how I made the server-side search :
private function _get_datatables_query()
{
$this->db->from($this->table);
$i = 0;
foreach ($this->column_search as $item) // loop column
{
if($_POST['sSearch']) // if datatable send POST for search
{
if($i===0) // first loop
{
$this->db->group_start(); // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
$this->db->like($item.'::varchar', $_POST['sSearch']);
}
else
{
$this->db->or_like($item.'::varchar', $_POST['sSearch']);
}
if(count($this->column_search) - 1 == $i) //last loop
$this->db->group_end(); //close bracket
}
$i++;
}
if(isset($_POST['iSortCol_0'])) // here order processing
$this->db->order_by($this->column_order[$_POST['iSortCol_0']], $_POST['sSortDir_0']);
else if(isset($this->order))
{
$order = $this->order;
$this->db->order_by(key($order), $order[key($order)]);
}
}
At runtime I got error because the cast is written like this : "some_column::varchar" like '%search_data%' ; it should be like this : "some_column"::varchar like '%search_data%'
So how to cast the column when calling $this->db->like ?
I found a trick by making a to_char when the column is the concerned one :
foreach ($this->column_search as $item) // loop column
{
if($_POST['sSearch']) // if datatable send POST for search
{
if($i===0) // first loop
{
$this->db->group_start(); // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
if ($item == 'ladate')
$item = "ltrim(to_char(ladate,'99999999'))";
$this->db->like($item, $_POST['sSearch']);
}
else
{
if ($item == 'ladate')
$item = "ltrim(to_char(ladate,'99999999'))";
$this->db->or_like($item, $_POST['sSearch']);
}
if(count($this->column_search) - 1 == $i) //last loop
$this->db->group_end(); //close bracket
}
$i++;
}

Access an array item in Perl after generating that array

Hello I want to access an specific array item based in a condition previously checked. I leave the code here:
elsif (scalar(#{$boss->bosses}) > 1) {
foreach my $pa (#{$boss->bosses}) {
my $p = My::Model::Group->new(id => $pa->group_id);
push(#$groups, $p);
$valid_pass = 1 if ($pa->checkPassword($self->param('password')));
}
if ($valid_pass) {
my $pa_id = $pa->id;
my $pa_partner_id = $pa->group_id;
}
else {
}
}
What I want to do is, if that if in the array that comes, I check if the password is correct, so if it's correct, then I want to take the id and the group_id of the array item to use it in a function to be able to log them in.
Your for loop is doing two things at once: producing a list of My::Model::Group objects in #$groups, and finding the first boss whose password checks out.
I suggest that you split them up into two clear operations, and the List::Util modules first operator is ideal for the second task
Here's how it would look. I've extracted the result of the method call $boss->bosses into a variable $bosses to avoid repeated calls to the method
Note that you don't need to apply scalar to an array when checking its size. The > and all the other comparators impose scalar context anyway
I've taken much of my code from your question, and I'm a little concerned that you extract values for $pa_id and $pa_partner_id and then just discard them. But I imagine that you know what you really want to do here
use List::Util 'first';
my $bosses = $boss->bosses;
if ( ... ) {
...;
}
elsif ( #$bosses > 1 ) {
#$groups = map { My::Model::Group->new( id => $_->group_id ) } #$bosses;
my $password = $self->param( 'password' );
my $pa = first { $_->checkPassword( $password ) } #$bosses;
if ( $pa ) {
my $pa_id = $pa->id;
my $pa_partner_id = $pa->group_id;
}
else {
...;
}
}

Checking form submission against a word list

I have some code to check is a form is being spammed and if so then stop the email.
It includes a section like this:
if(strpos($messagefield, " cialis") !== false){
$noemail = true;
}
if(strpos($messagefield, " viagra") !== false){
$noemail = true;
}
etc for as many words as we have in the bad word list
This works fine, but is clumsy and difficult to easily add new words to check.
It would be easier if I could create an array and check any field against the array, but I am strugling to find an example to use (most examples still specify the text to search for which defeats the object in this case)
Can anyone help with code to check $messagefield against an array?
(I know there are better ways maybe but this works for us at the moment!)
$i = 0;
$wordlist = array(' cialis', ' viagra');
while ($i < count($wordlist) && $noemail == false) {
if (strpos($messagefield, $wordlist[$i]) !== false) {
$noemail = true;
}
$i++;
}
It is better to use stripos (case-insensitive version of strpos).
Try following code:
$a = array(' cialis', ' viagra');
for ($i = 0; $i < count($a); $i++)
if(stripos($messagefield, $a[$i]) !== false){
$noemail = true;
break;
}
}

Perl: How to check what is being returned from a subroutine

I have a subroutine that will return two hashes when all goes well. But the sub checkouts output of command and if it matches a certain pattern, it returns with "-1". Is there anyway to check the return of the subroutine from where I called it?
Kinda like:
if (RETURN_VALUE == -1){
do something}
else
go as normal with the hashes
How could one function return two hashes?
If you mean hashrefs, the check would be quite simple:
my ($h1,$h2) = myFunction();
if ( !ref($h1) || (ref($h1) ne "HASH"))
{
die 'error';
}
You function should return references to the two hashes on success and nothing upon failure. Then you can just check the truth value of the function call.
sub myfunc {
my %hash1;
my %hash2;
return (\%hash1, \%hash2);
}
my $ref1;
my $ref2;
unless (($ref1, $ref2) = myfunc()) {
print "Something went wrong\n";
} else {
print "OK\n";
}
If you return two (or any number for that matter) hashes from a subroutine, the result will be a single hash. You will not be able to separate the original hashes from the result in a normal manner. Returning hash references will not exhibit this problem.
Suppose foo() returns two hash references when the pattern is matched and returns -1 when it does not match.
my ( $value_1, $value_2 ) = foo;
if ( $value_1 == -1 ) {
# pattern did not match
}
else { # for strict checks: elsif ( ref $value_1 eq 'HASH' && ref $value_2 eq 'HASH' ) {
# pattern matched
}