Filling a hash with parsed input elements [closed] - perl

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I would like to take a given input, say , and run specific parsings over it and fill a hash with the outputs of those parsings. For example, I'd like this input:
"barcodedSamples": "{\"I-735\":{\"barcodes\":[\"IonXpress_001\"]},\"13055\":{\"barcodes\":[\"IonXpress_002\"]}}",
to be parsed (using a combination of grep and some more specific fiddling that I don't have a strong grasp on) into a table that lists the barcodes and sample names as follows:
barcode sample
IonXpress_001 I-735
IonXpress_002 13055
where "barcode" and "sample" are treated as keys. Another example is that I would like to grep to a line that starts:
"library": "hg19",
and map the value "hg19" (so, the string inside the second set of quotation marks, programmatically speaking) to an arbitrary key like "lib":
Library
hg19

The string closely resembles JSON, however requires some cleaning up to become valid JSON.
#!/usr/bin/perl
use strict;
use warnings FATAL => qw/all/;
use JSON;
use Data::Dumper;
my $json_string = '"barcodedSamples": "{\"I-735\":{\"barcodes\":[\"IonXpress_001\"]},\"13055\":{\"barcodes\":[\"IonXpress_002\"]}}"';
$json_string =~ s/\\//g; # remove escape backslashes.
$json_string =~ s/"\{/{/; # remove an invalid opening quote.
chop $json_string; # remove an invalid closing quote.
$json_string = '{' . $json_string . '}'; # wrap in curly braces.
my $json_object = JSON->new( );
my $perl_ref = $json_object->decode( $json_string );
print Dumper( $perl_ref );

That string you're parsing looks suspiciously like JSON. Why not just use the JSON module (which comes with newer Perls, but can be installed from CPAN for older ones) instead of writing your own parser?

Related

Need to grep a string from a line in a variable and store it in another variable [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a variable $abc that contains the line like below:
abc.txt -> check a/b/c test
I need to get abc.txt in another variable say $bcd and a/b/c in the variable say $xyz. I have the regex to do so but I don't know how I can do it using perl as in my knowledge perl grep and perl map can be used on arrays only not variables.
my ($bcd) = split(/\s*->\s*/, $abc, 2);
my $bcd = $abc =~ s/\s*->.*//sr;
my ($bcd) = $abc =~ /^(?:(?!\s*->).)*)/s;
my ($bcd) = $abc =~ /^(.*?)\s*->/s;
All but the last returns the entire input string if there's no ->.

Inconsistency in misuse of "reverse" in list context [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
print reverse "word"; # prints 'word'
print reverse foreach ("word"); # prints nothing (empty string)
I am using Perl v5.24.
list context is forced by print, and these statements are "bad"
because reverse should be called in scalar contest to be useful.
Nevertheless, why the inconsistency?
print reverse foreach ("word"); # prints nothing (empty string)
What you have written is
for ( 'word' ) {
print reverse();
}
That code clearly executes the loop just once with $_ set to word, and prints a reversed empty list
Perhaps you should avoid statement modifiers until you are more familiar with the language
As tjd comments, reverse will reverse either a list or a string. In list context (as imposed by the call to print) it expects a list of parameters to reverse, and ignores $_. In scalar context it would just concatenate all parameters passed to it and reverse the resulting string; in the absence of any parameters it will reverse the string in $_
The reverse can indeed be used in either scalar context
perl -wE'$w = "hello"; $r = reverse $w; say $r' # olleh
or in list context
perl -wE'say join " ", reverse qw(hello there)' # there hello
Both are useful and there is no "inconsistency" in these behaviors.
One thing to watch out for is that when a list is used in scalar context
perl -wE'say scalar reverse qw(hello there)' # erehtolleh
then the list gets concatenated and reverse returns a string with characters in reverse order.
I am adding another "gotcha" for completeness, even as it has been covered in other answers.
The reverse defaults to $_ in scalar context, as expected. However, in list context it just doesn't take $_, and in for (#ary) { print reverse; }, with list context imposed on it by print, it has no arguments and thus prints nothing.
In scalar context, reverse reverses the characters of a string.
my $s = "abc";
$s = reverse($s);
say $s;
# cba
In list context, reverse reverses the scalars of its argument list.
my #a = qw( abc def ghi );
#a = reverse(#a);
say "#a";
# ghi def abc
Clearly, both uses are very consistent with each other. The only possible lack of consistency between scalar-context reverse and list-context reverse is what happens when you provide no argument expression. Scalar-context reverse defaults to using $_, but doing so would make no sense for list-context reverse, so it doesn't treat that case specially.
That means the reason print reverse for "word"; prints nothing is that the reverse of zero items is zero items.

In Perl what is the difference between double quotes("), single quotes(') and grave accent(`) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
In Perl, what is the difference between quoting with double quotes("), single quotes('), and grave accents(`)?
This code:
#!/bin/env perl
use v5.10;
say "Hello";
say 'Hi';
say `Hola`;
gives the following result:
Hello
Hi
Single quotes ''
Construct strings without interpolation. There is also a q() operator that does the same.
my $foo = 'bar';
print '$foo'; # prints the word $foo
print q($foo); # is equivalent
You would use single quotes when you just have text and there are no variables inside the text.
Double quotes ""
Construct strings with interpolation of variables. There is also a qq() operator that does the same.
my $foo = 'bar';
print "$foo"; # prints the word bar
print qq($foo); # is equivalent
Use these if you want to put variables into your string. A typical example would be in an old-fashioned CGI program, where you see this:
print "<td>$row[0]</td>";
The qq() variant comes in handy if your text contains double-quotes.
print qq{$link_text}; # I prefer qq{} to qq()
This is way easier to read than escape all the quotes.
print "$link_text"; # this is hard to read
Backticks ``
Shell out and execute a command. The return value of the other program is returned. There is also a qx() operator that does the same. This interpolates variables.
print `ls`; # prints a directory listing of the working directory
my $res = qx(./foo --bar);
Use this if you want to write a script that is a bit more powerful than a shell script, where you need to call external programs and capture their output.
All the interpolating ones can only interpolate variables, not commands.
my $foo = 1;
my $bar = 2;
print "$foo + $bar";
This will print 1 + 2. It will not actually calculate and print 3.
All of those (and more) are explain in perlop under Quote and Quotelike operators.

Im using Perl for the first time [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
Im taking a Bioinformatics class and I keep getting an "Undefined subroutine &main::Print called at ReverseComp.txt line 4." error
# ReverseComp.txt => takes DNA sequence from user
# and returns the reverse complement
print ("please input DNA sequence:\n");
$DNA =<STDIN>;
$DNA =~tr/ATGC/TACG/; # Find complement of DNA sequence
$DNA =~reverse ($DNA); # Reverse DNA sequence
print ("Reverse complement of sequence is:\n");
print $DNA."\n";
This is my code and I have tried a few different things with line 4 but with no results. Any suggestions? (I am writing this from a prompt, everything looks right....)
I have some notes related to your code:
Name your scripts with the .pl extension instead of .txt. That is the common accepted extension for Perl scripts (and the .pm for Perl modules, libraries with reusable code)
Always start your scripts with use strict; use warnings;. These sentences helps you to avoid common mistakes.
Declare your variables before you use it (See the my function)
chomp your input from STDIN to remove the newline at the end.
The call to reverse function is odd. I think that $DNA =~ reverse ($DNA); should be $DNA = reverse ($DNA);
The reverse function is more common used with Perl arrays; with a string you get the reversed version of that string, as I guest you expected.
The print function may take a list of parameters, so you can print several things in one sentence
You can omit parentheses in many places, e.g. reverse($a) is the same as reverse $a. Both are valid, but the latter is more suitable to the Perl style of writing code. The Perl style guide is a recommended read
Related to your question, I think your script is right, because the print function exists in Perl, and the error you got says about Print (with uppercase, which is important in Perl). You maybe run a different script that you have posted here.
This is your script with the previous considerations applied (ReverseComp.pl):
use strict;
use warnings;
print "please input DNA sequence:\n";
chomp( my $DNA = <STDIN> );
$DNA =~ tr/ATGC/TACG/; # Find complement of DNA sequence
$DNA = reverse $DNA; # Reverse DNA sequence
print "Reverse complement of sequence is:\n", $DNA, "\n";
In any case, welcome to the fantastic Perl world, and be prepared to enjoy your trip.

Randomizing 3 lines to display in CGI with Perl [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm trying to write a CGI script that will take three lines of text and randomize them. Each time you view the webpage, the three lines will appear one after the other in a different order each time. How do I do this and what is the code?
perldoc -q "random line"
Found in D:\sb\perl\lib\perlfaq5.pod
How do I select a random line from a file?
Short of loading the file into a database or pre-indexing the lines in
the file, there are a couple of things that you can do.
Here's a reservoir-sampling algorithm from the Camel Book:
srand;
rand($.) < 1 && ($line = $_) while <>;
This has a significant advantage in space over reading the whole file
in. You can find a proof of this method in *The Art of Computer
Programming*, Volume 2, Section 3.4.2, by Donald E. Knuth.
You can use the File::Random module which provides a function for that
algorithm:
use File::Random qw/random_line/;
my $line = random_line($filename);
Another way is to use the Tie::File module, which treats the entire file
as an array. Simply access a random array element.
or
perldoc -q shuffle
Found in D:\sb\perl\lib\perlfaq4.pod
How do I shuffle an array randomly?
If you either have Perl 5.8.0 or later installed, or if you have
Scalar-List-Utils 1.03 or later installed, you can say:
use List::Util 'shuffle';
#shuffled = shuffle(#list);
If not, you can use a Fisher-Yates shuffle.
sub fisher_yates_shuffle {
my $deck = shift; # $deck is a reference to an array
return unless #$deck; # must not be empty!
my $i = #$deck;
while (--$i) {
my $j = int rand ($i+1);
#$deck[$i,$j] = #$deck[$j,$i];
}
}
use List::Util qw( shuffle );
#lines = shuffle(#lines);