Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Ellie Crabcakes
Feb 1, 2008

Stop emailing my boyfriend Gay Crungus

Hughmoris posted:

I'm pretty unfamiliar with how modules are installed but it seemed like everything failed. Unfortunately I didn't save a copy of the log before I fixed the problem so I can only give vague answers
That's just some general advice. When you have the actual error messages on hand, you get answers faster.

Adbot
ADBOT LOVES YOU

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Hughmoris posted:

Lots and lots.


I took your advice and hopped on perl IRC. Someone was nice enough to help me out. They had me install the perl module local::lib for reasons I don't fully understand but I'm up and running now. Just created my first "Hello world!" web app. :3:

Was it mst?

Anyhow, if local::lib is suggested, you usually don't have convenient root access, and local::lib allows you to install modules just anywhere and then point the code at that.

Hughmoris
Apr 21, 2007
Let's go to the abyss!

Mithaldu posted:

Was it mst?

Anyhow, if local::lib is suggested, you usually don't have convenient root access, and local::lib allows you to install modules just anywhere and then point the code at that.

Yep, it was mst.

Lacking a project, I decided to tackle reddit's easy Weekly Programming Challenge. The goal is to calculate the standard deviation of a given list of values and round to 4 decimal places. I have a working solution but my code looks extremely clunky. Any tips on where I could improve it for best practice/style?
Perl code:
use warnings;
use strict;
use diagnostics;

sub std_dev {
    my @values = @_;
    my $numberOfInputs = @values;
    my $total = 0;
    my $mean = 0;
    my $squareDiff = 0;

    foreach(@values)
    {
        $total += $_;
    }

    $mean = $total / $numberOfInputs;

    foreach(@values)
    {
        $squareDiff += ($_ - $mean)**2;
    }
    my $standard_deviation = sqrt($squareDiff / $numberOfInputs);

    print "The standard deviation is: " . (sprintf "%.4f", $standard_deviation) . "\n";

}

my @input = qw(37 81 86 91 97 108 109 112 112 114 115 117 121 123 141);
std_dev(@input);
Which will give me an output of: 23.2908

Hughmoris fucked around with this message at 04:50 on May 16, 2015

toadee
Aug 16, 2003

North American Turtle Boy Love Association

You can bum lines of perl all day and turn it into barely intelligible nonsense. That code is readable and does what it says on the tin.

Toshimo
Aug 23, 2012

He's outta line...

But he's right!

Hughmoris posted:

I have a working solution but my code looks extremely clunky.

Nonsense.

It could always look worse.

Perl code:
use warnings;
use strict;
use diagnostics;

sub std_dev {
    my @values = @_;
    my $mean = 0;
    my $squareDiff = 0;

    map { $mean += $_ / @values} @values;
    map { $squareDiff += ($_ - $mean)**2 } @values;

    my $standard_deviation = sqrt($squareDiff / @values);

    print "The standard deviation is: " . (sprintf "%.4f", $standard_deviation) . "\n";

}

my @input = qw(37 81 86 91 97 108 109 112 112 114 115 117 121 123 141);
std_dev(@input);

Toshimo fucked around with this message at 06:06 on May 16, 2015

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Is there any reason you used map, instead of postfix for?
Perl code:
    $mean += $_ / @values for @values;
    $squareDiff += ($_ - $mean)**2 for @values;
}
-
-


Hughmoris posted:

Yep, it was mst.

Nice, and nice code. :)

Have you seen http://perl-tutorial.org yet?

Hughmoris
Apr 21, 2007
Let's go to the abyss!

Mithaldu posted:

Is there any reason you used map, instead of postfix for?
Perl code:
    $mean += $_ / @values for @values;
    $squareDiff += ($_ - $mean)**2 for @values;
}
-
-


Nice, and nice code. :)

Have you seen http://perl-tutorial.org yet?

Yep, I have that site bookmarked.

I know I've remarked on it earlier but web scraping is an exercise in frustration for me. There doesn't seem to be many newbie-friendly tutorials out there for Perl, so I've been trying to easter-egg my way solutions. For this problem, I'm trying to scrape a page that has the highest points in each state. Using the Web::Scraper module that someone suggested earlier, I'm able to get some information. I want to print just the state name and it's corresponding elevation value, NOT the highest point. Unfortunately, what I have scrapes all 3 values and I'm not sure how to adjust it.
Perl code:
use Modern::Perl '2015';
use diagnostics;
use Web::Scraper;
use URI;
use Encode;
use List::MoreUtils qw(natatime);

my $states = scraper {
	process "table#t1 tbody tr td", 'places[]' => 'TEXT';
};

my $res = $states->scrape( URI->new("http://highpointers.org/us-highpoint-guide") );

foreach my $state (@{$res->{places}}){
	say "$state";
}
Any ideas?

*And my variable naming convention is all jacked up due to repeatedly guessing at a solution. Initially I was just trying to grab the state names but it's grabbing everything in the table. :(

Hughmoris fucked around with this message at 04:40 on May 18, 2015

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Two things:

1. You want to have a structure that contains more structures. If i read the docs of Web::Scraper right, that means you need to have one scraper that finds the structure which contains the structures that have the data you want (i.e. scrape for the trs), which then passes on to a subscraper that converts the individual TDs into text. That way you end up with an array that contains arrays, and can go through each group and grab the first and third value.

2. I highly recommend not using foreach, since it's literally just an alias to for. There is no advantage to it.

syphon
Jan 1, 2001

Mithaldu posted:

2. I highly recommend not using foreach, since it's literally just an alias to for. There is no advantage to it.
Really? I've always trended towards foreach, only because it's more explicit. Is there any advantage to sticking with just "for"?
Perl code:
foreach my $person (@people) {
   # it's very explicit what $person is here
}
as opposed to
Perl code:
for (@people) {
    # $_ can be used , but is ambiguous
}
At this point I suppose the obvious answer is to slap in a "my $person = $_", but the foreach feels more elegant to me.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

syphon posted:

Really? I've always trended towards foreach, only because it's more explicit. Is there any advantage to sticking with just "for"?
Perl code:
foreach my $person (@people) {
   # it's very explicit what $person is here
}
as opposed to
Perl code:
for (@people) {
    # $_ can be used , but is ambiguous
}
At this point I suppose the obvious answer is to slap in a "my $person = $_", but the foreach feels more elegant to me.

You know that you can declare a named variable for the current element of whatever you're iterating over with the for form in the same way you can with the foreach form, right?

e: cf. http://codepad.org/efwlG7kH

Blotto Skorzany fucked around with this message at 01:12 on May 19, 2015

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

syphon posted:

Really? I've always trended towards foreach, only because it's more explicit. Is there any advantage to sticking with just "for"?
Just in case Blotto's post didn't make it more clear (though i'm unclear how saying "it's an alias" is not clear enough): The advantage to for is four letters less to type AND less to read for developers who come after you, since aside from the letters "each", for and foreach are literally the same thing. They're different names that result in identical code.

Ellie Crabcakes
Feb 1, 2008

Stop emailing my boyfriend Gay Crungus

Mithaldu posted:

Just in case Blotto's post didn't make it more clear (though i'm unclear how saying "it's an alias" is not clear enough): The advantage to for is four letters less to type AND less to read for developers who come after you, since aside from the letters "each", for and foreach are literally the same thing. They're different names that result in identical code.
Which doesn't really strike me as being a very meaningful advantage.

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
Put another way, "more letters" doesn't mean "more explicit".

Hughmoris
Apr 21, 2007
Let's go to the abyss!

Mithaldu posted:

Two things:

1. You want to have a structure that contains more structures. If i read the docs of Web::Scraper right, that means you need to have one scraper that finds the structure which contains the structures that have the data you want (i.e. scrape for the trs), which then passes on to a subscraper that converts the individual TDs into text. That way you end up with an array that contains arrays, and can go through each group and grab the first and third value.

2. I highly recommend not using foreach, since it's literally just an alias to for. There is no advantage to it.

I couldn't quite get it to work the way you mentioned. I did however discover a List::MoreUtils function called natatime that allows me to print an array in chunks. This code allows me to print the state and it's corresponding elevation:
Perl code:
use Modern::Perl '2015';
use diagnostics;
use Web::Scraper;
use URI;
use Encode;
use List::MoreUtils qw(natatime);

my $website = scraper {
    process "table#t1 tbody tr td", 'places[]' => 'TEXT';
};

my $results = $website->scrape( URI->new("http://highpointers.org/us-highpoint-guide") );


my @array;

for(@{$results->{places}}){
	push @array, $_;
}


my $it = natatime 3, @array;
while (my @vals = $it->())
{
  print "$vals[0]\t\t\t$vals[2]\n";
}
I can't say I really understand what's going on here: while (my @vals = $it->())

Hughmoris fucked around with this message at 03:17 on May 19, 2015

Sebbe
Feb 29, 2004

Hughmoris posted:

I can't say I really understand what's going on here: while (my @vals = $it->())

When you call natatime , you get back a (reference to a) subroutine. Whenever you call this subroutine (i.e., the $it->() call), it gives you the n (in this case 3) next elements of the list you provided. The while-loop then terminates once there are no more values to return, since the empty list is a falsy value.

If you're curious, you can see the implementation here.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

John Big Booty posted:

Which doesn't really strike me as being a very meaningful advantage.
Using exclusively for has no a gigantic advantage, but it has a concrete, distinct and real one, that comes with literally no disadvantages weighing up against it. Meanwhile using foreach has the disadvantage that it makes people think it's actually different somehow, as demonstrated here.

Hughmoris posted:

I couldn't quite get it to work the way you mentioned.
Never just say that, always also describe what you tried, since it likely points towards a gap in your knowledge that can be usefully filled. :)

Anyhow, great to hear you managed to get it to be how you wanted it.

Hughmoris
Apr 21, 2007
Let's go to the abyss!

Sebbe posted:

When you call natatime , you get back a (reference to a) subroutine. Whenever you call this subroutine (i.e., the $it->() call), it gives you the n (in this case 3) next elements of the list you provided. The while-loop then terminates once there are no more values to return, since the empty list is a falsy value.

If you're curious, you can see the implementation here.

Thanks, that breakdown makes sense.


Anyone here working on any Perl projects? Anyone work with Perl for their day to day jobs? Anyone else currently trying to learn Perl? If so, do tell.

Hughmoris fucked around with this message at 00:37 on May 27, 2015

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Hughmoris posted:

Anyone here working on any Perl projects? Anyone work with Perl for their day to day jobs? Anyone else currently trying to learn Perl? If so, do tell.
In private: https://github.com/wchristian/Microidium

And in day job terms i've been doing Perl since 2005, and i still learn new things. (The locale affects how sprintf works!)

Anaconda Rifle
Mar 23, 2007

Yam Slacker

Hughmoris posted:

Thanks, that breakdown makes sense.


Anyone here working on any Perl projects? Anyone work with Perl for their day to day jobs? Anyone else currently trying to learn Perl? If so, do tell.

My team uses Perl for scripting. We built a suite of scripts that help us and the developers work in the environment.

ephphatha
Dec 18, 2009




We use perl where i work for a few websites/web-accessible forms and for a bunch of scripts. I tend to use it whenever I need to write scripts or reports that may eventually need to be rerun by someone else since our environment supports it.

abigserve
Sep 13, 2009

this is a better avatar than what I had before
I am developing a simple application for managing firewall rules, the backend that interfaces with the actual device (all Cisco ASA's) is written in perl because I need good regex capabilities. In retrospect I could have used PHP but I already had a standard set of custom perl functions left over from previous projects. I've also used it in the past to create a simple cli interface for blacklisting/quarantining devices on a network (paired with Expect).

fuck the mods
Mar 30, 2015

Hughmoris posted:

Thanks, that breakdown makes sense.


Anyone here working on any Perl projects? Anyone work with Perl for their day to day jobs? Anyone else currently trying to learn Perl? If so, do tell.

Don't use natatime to parse a Web::Scraper data structure. If you need some more example code you could take a look at https://github.com/ugexe/SomethingAwful--Forums/blob/master/lib/SomethingAwful/Forums/Scraper/Forum.pm

Web::Scraper is just a thin DSL for xpath, so if something isn't working the way you think it should its probably your xpath.

Hughmoris posted:

Thanks, that breakdown makes sense.


Anyone here working on any Perl projects? Anyone work with Perl for their day to day jobs? Anyone else currently trying to learn Perl? If so, do tell.

I use Perl5 and Perl6 for $work in sports analytics (lots of Web::Scraper stuff)

homercles
Feb 14, 2010

Is there a stripped down vi clone written in Perl?

Hughmoris
Apr 21, 2007
Let's go to the abyss!

gently caress the mods posted:

Don't use natatime to parse a Web::Scraper data structure. If you need some more example code you could take a look at https://github.com/ugexe/SomethingAwful--Forums/blob/master/lib/SomethingAwful/Forums/Scraper/Forum.pm

Web::Scraper is just a thin DSL for xpath, so if something isn't working the way you think it should its probably your xpath.


I use Perl5 and Perl6 for $work in sports analytics (lots of Web::Scraper stuff)

How are you liking Perl6?

fuck the mods
Mar 30, 2015
I like it, it's just slow and the ecosystem is lacking (although active and growing). When Inline::Perl5 works you can even subclass perl 5 code and do stuff like
code:

    use Inline::Perl5;
    use DBI:from<Perl5>;

    my $dbh = DBI.connect('dbi:Pg:database=test');
    my $products = $dbh.selectall_arrayref(
        'select * from products', {Slice => {}}
    );

du -hast
Mar 12, 2003

BEHEAD THOSE WHO INSULT GENTOO
I'm fairly new to perl, is the "my" statement when declaring a variable necessary? Does it somehow differentiate between local/global?

Edit: and an actual question-question:

I am learning perl on a sandbox linux server, thinking that it will come in handy for system administration / computer janitoring.

One of the things that I was attempting to do was useradd.

code:
        system("useradd $user") or die "Unable to add user.";

useradd spits out an error (useradd: user 'goatseguy69' already exists) if this command is run twice (since the user was already created). How can I capture that return text / error so I can have my script inform me that it was unsuccessful? How does it return a value (ie, is it True if it doesn;t error and False if it does?).



last edit: I know that this is dangerous / unsecure as hell to do, just trying to learn the basics.

du -hast fucked around with this message at 12:43 on Jul 13, 2015

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

I'm not sure what you're learning from, but the likelihood that your learning material is horrible is high. Please have a look at http://perl-tutorial.org for learning materials that are known to not be hostile to newbies.

As for my, it is not strictly necessary and you can program without it, however it is strongly recommended to use my and use strict; use warnings; in conjunction as that protects you from many bugs.

Global/local: You want to learn about lexical scoping, it's a bunch to explain, so please look it up.

Getting STDERR from child processes: https://metacpan.org/pod/Capture::Tiny

Return value: http://perldoc.perl.org/functions/system.html , in short, use code like this:

code:
use strict;
use warnings;
use Capture::Tiny;
my $user = "blah";
my ( $out, $err, $ret ) = capture {
    system( "useradd $user" );
};
die $err if $err or $ret;

qntm
Jun 17, 2009

du -hast posted:

I'm fairly new to perl, is the "my" statement when declaring a variable necessary? Does it somehow differentiate between local/global?

Basically, yes and yes. my declares a local (i.e. locally scoped, lexical) variable.

Perl code:
my $qux = "what";
In general you should always use my for your variables until you start needing globals. As for globals, that's a bit weird. Perl's global variables are namespaced by package.

Perl code:
$main::foo = 37;
# creates/sets the global scalar variable "foo" in package "main"

@Some::Package::bar = (1, 2, 3);
# creates/sets the global array variable "bar" in package "Some::Package"
If you drop the my from a variable declaration, then what you actually end up doing is creating/setting a global variable with the package name is filled in implicitly. By default (i.e. at the top of a Perl script) you are in the main package:

Perl code:
$baz = "what";
print $main::baz; # "what"
but you can switch packages using the package built-in:

Perl code:
package Some::Package;
print $bar[0]; "1"
print $foo; # Looks for $Some::Package::foo, finds undef, prints the empty string
Luckily, if you turn on use strict; (which you should, always), you are prevented from implicitly accessing global variables in this way. $baz = "what"; becomes a compilation error.

qntm fucked around with this message at 16:55 on Jul 13, 2015

Hughmoris
Apr 21, 2007
Let's go to the abyss!
I'm still new to Perl but I just wrote a script for work that will scrape a Lotus Notes database and write content to an Excel sheet, with requested formatting. I don't know how other languages compare on those items but Perl made it a breeze. :3:

Hughmoris fucked around with this message at 00:03 on Aug 13, 2015

Hughmoris
Apr 21, 2007
Let's go to the abyss!
Well, I may have spoke too soon. I think I'm getting hung up on dereferencing. I have a block of code that looks something like this:
Perl code:
my $doc = $view->GetFirstDocument;
$doc->{Scope}->[0];
$doc->{Delegate}->[0];
$doc->{LastAct}->[0];
and it is outputting this:
code:
Small
Sarah
Win32::OLE::Variant=SCALAR(0x3d5ef80)
I'm not positive how to derefence $doc->{LastAct}->[0] further and get to the value. The first two items are strings, and the problem item is a date/time stamp if that makes any difference. Any ideas?

Hughmoris fucked around with this message at 04:43 on Aug 13, 2015

Ellie Crabcakes
Feb 1, 2008

Stop emailing my boyfriend Gay Crungus

Hughmoris posted:

Well, I may have spoke too soon. I think I'm getting hung up on dereferencing. I have a block of code that looks something like this:
Perl code:
my $doc = $view->GetFirstDocument;
$doc->{Scope}->[0];
$doc->{Delegate}->[0];
$doc->{LastAct}->[0];
and it is outputting this:
code:
Small
Sarah
Win32::OLE::Variant=SCALAR(0x3d5ef80)
I'm not positive how to derefence $doc->{LastAct}->[0] further and get to the value. The first two items are strings, and the problem item is a date/time stamp if that makes any difference. Any ideas?
code:
$doc->{LastAct}->[0]->Value()
should do it.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

John Big Booty posted:

code:
$doc->{LastAct}->[0]->Value()
should do it.
You mean:
code:
$doc->{LastAct}[0]->Value
Seriously, at least try and give newbies examples in idiomatic Perl. :(

Ellie Crabcakes
Feb 1, 2008

Stop emailing my boyfriend Gay Crungus

Mithaldu posted:

You mean:
code:
$doc->{LastAct}[0]->Value
Seriously, at least try and give newbies examples in idiomatic Perl. :(
Ok.
code:
 *{ref($doc->{LastAct}[0])."::".(grep {/value/i} keys %{ref($doc->{LastAct}[0])."::"})[0]}->();

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

John Big Booty posted:

grep {/value/i}
A true perler would've known to use a comma there, i'm going to have to confiscate your card.

Ellie Crabcakes
Feb 1, 2008

Stop emailing my boyfriend Gay Crungus

Mithaldu posted:

A true perler would've known to use a comma there, i'm going to have to confiscate your card.
code:
use MIME::Base64;
print join(" ",(grep {!/[0-9]/} map {decode_base64($_)} qw(dXI= Y29tbWFz MTIzNGR3ZQ== cDAwcA== Y2Fu MHhmZjk5YWEzMzQ0 NjY2 c3Vjaw== NTQ1NjNoZ3JyZjMy aXQ=)),"\n");

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

John Big Booty posted:

code:
use MIME::Base64;
print join(" ",(grep {!/[0-9]/} map {decode_base64($_)} qw(dXI= Y29tbWFz MTIzNGR3ZQ== cDAwcA== Y2Fu MHhmZjk5YWEzMzQ0 NjY2 c3Vjaw== NTQ1NjNoZ3JyZjMy aXQ=)),"\n");
A true perler also has a sense of humor.

syphon
Jan 1, 2001

Mithaldu posted:

A true perler also has a sense of humor.

I've met a few true perlers and I wouldn't be so sure of that...

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

syphon posted:

I've met a few true perlers and I wouldn't be so sure of that...

To be honest, i'm biased by IRC and ShadowCat specifically. If you've interacted with schmorp, then well, my sympathies. :v:

Ellie Crabcakes
Feb 1, 2008

Stop emailing my boyfriend Gay Crungus

Mithaldu posted:

A true perler also has a sense of humor.
You kind of have to, if being a True Perler is important to you.

Adbot
ADBOT LOVES YOU

welcome to hell
Jun 9, 2006

Mithaldu posted:

You mean:
code:
$doc->{LastAct}[0]->Value
Seriously, at least try and give newbies examples in idiomatic Perl. :(
Even among the IRC crowd you aren't going to see a lot of consistency on style preferences for minor things like this.

  • Locked thread