Published by Erza Scarlet on Friday 29 March 2024 10:04
I am writing a perl script which uses some fields from "df" command.
my $command = "df -a";
my $output = `$command`;
# my $outputs = qx/df/;
print "$output\n\n\n";
This is giving me output as follows-
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 4096 8 4088 1% /dev
tmpfs 40925604 24 40925580 1% /dev/shm
tmpfs 9864920 9180 9855740 1% /run
tmpfs 4096 0 4096 0% /sys/fs/cgroup
/dev/sda3 20937708 12632092 8305616 61% /
/dev/sda2 20422 6266 14156 31% /boot/efi
/dev/sdb 41922560 5476428 36446132 14% /data
tmpfs 4932456 0 4932456 0% /run/user/0
bkpteam:/swdepot 587202560 308491328 278711232 53% /mnt
tmpfs 4932456 0 4932456 0% /run/user/58037
server_name:/db_share/Restore_NewDB/ABC_import/trans 25163737088 2580348928 22583388160 11% /xyz/ABC/trans
However, when I execute "df -a" command directly on Linux, i am getting the following output-
Filesystem Size Used Avail Use% Mounted on
proc 0 0 0 - /proc
sysfs 0 0 0 - /sys
devtmpfs 4.0M 8.0K 4.0M 1% /dev
securityfs 0 0 0 - /sys/kernel/security
tmpfs 40G 24K 40G 1% /dev/shm
devpts 0 0 0 - /dev/pts
tmpfs 9.5G 9.0M 9.4G 1% /run
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup
cgroup2 0 0 0 - /sys/fs/cgroup/unified
cgroup 0 0 0 - /sys/fs/cgroup/systemd
pstore 0 0 0 - /sys/fs/pstore
efivarfs 0 0 0 - /sys/firmware/efi/efivars
bpf 0 0 0 - /sys/fs/bpf
cgroup 0 0 0 - /sys/fs/cgroup/cpu,cpuacct
cgroup 0 0 0 - /sys/fs/cgroup/net_cls,net_prio
cgroup 0 0 0 - /sys/fs/cgroup/perf_event
cgroup 0 0 0 - /sys/fs/cgroup/freezer
cgroup 0 0 0 - /sys/fs/cgroup/blkio
cgroup 0 0 0 - /sys/fs/cgroup/misc
cgroup 0 0 0 - /sys/fs/cgroup/hugetlb
cgroup 0 0 0 - /sys/fs/cgroup/devices
cgroup 0 0 0 - /sys/fs/cgroup/memory
cgroup 0 0 0 - /sys/fs/cgroup/cpuset
cgroup 0 0 0 - /sys/fs/cgroup/pids
cgroup 0 0 0 - /sys/fs/cgroup/rdma
/dev/sda3 20G 13G 8.0G 61% /
systemd-1 - - - - /proc/sys/fs/binfmt_misc
debugfs 0 0 0 - /sys/kernel/debug
mqueue 0 0 0 - /dev/mqueue
tracefs 0 0 0 - /sys/kernel/tracing
hugetlbfs 0 0 0 - /dev/hugepages
fusectl 0 0 0 - /sys/fs/fuse/connections
configfs 0 0 0 - /sys/kernel/config
none 0 0 0 - /run/credentials/systemd-sysusers.service
/dev/sda2 20M 6.2M 14M 31% /boot/efi
/dev/sdb 40G 5.3G 35G 14% /data
tracefs 0 0 0 - /sys/kernel/debug/tracing
tmpfs 4.8G 0 4.8G 0% /run/user/0
bkpteam:/swdepot 560G 295G 266G 53% /mnt
tmpfs 4.8G 0 4.8G 0% /run/user/58037
binfmt_misc 0 0 0 - /proc/sys/fs/binfmt_misc
/dev/sdb 40G 5.3G 35G 14% /usr/FFF
/dev/sdb 40G 5.3G 35G 14% /xyz/ABC
servername:/db_share/Restore_NewDB/ABC_import/trans 24T 2.5T 22T 11% /xyz/ABC/trans
Later on in the script, i have a regex which captures lines containing the either "/xyz/ABC" or "/usr/FFF".
You can see that "df" command, when ran in linux, contain 3 such lines as follows-
servername:/db_share/Restore_NewDB/ABC_import/trans 24T 2.5T 22T 11% /xyz/ABC/trans
/dev/sdb 40G 5.3G 35G 14% /usr/FFF
/dev/sdb 40G 5.3G 35G 14% /xyz/ABC
However, the 'df -a' output in perl script does not capture the last two lines mentioned in the expected results. The filesystem in Linux is such that "/dev/sdb" has 3 mounts present on it and "df -a" executed vua perl script is able to capture only the first entry which does not contain either of the regex.
This is messing up with the flow of the script as we need the values "/xyz/ABC" or "/usr/FFF". We don't directly use "/xyz/ABC" or "/usr/FFF" as ABC and FFF are script inputs and further used in other logic involving some nested paths.
Please help in the situation, how to capture the entire "df" output by perl script.
Published by vanarie on Friday 29 March 2024 09:23
A few days ago Webmin S3 site backups began to fail. Error notice was as follows:
Can't locate Time/Piece.pm in @INC (@INC contains: /vendor_perl /usr/libexec/webmin /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 . .. .. /usr/libexec/webmin/virtual-server) at Net/Amazon/Signature/V4.pm line 8. BEGIN failed--compilation aborted at Net/Amazon/Signature/V4.pm line 8. Compilation failed in require at S3/AWSAuthConnection.pm line 28. BEGIN failed--compilation aborted at S3/AWSAuthConnection.pm line 28. Compilation failed in require at (eval 399) line 2. BEGIN failed--compilation aborted at (eval 399) line 2.
I went to the backup config and the S3 Accounts complained that perl(S3::AWSAuthConnection) was not installed, but it was unavailable when trying to install from command line or the Perl Modules interface.
Installing package(s) with command /bin/yum -y install perl(S3::AWSAuthConnection) ..
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirror.steadfastnet.com
* centos-sclo-rh: mnvoip.mm.fcix.net
* centos-sclo-sclo: mnvoip.mm.fcix.net
* epel: epel.stl.us.ssimn.org
* extras: nyc.mirrors.clouvider.net
* remi-php74: mirror.usi.edu
* remi-safe: mirror.usi.edu
* rpmfusion-free-updates: muug.ca
* updates: linux-mirrors.fnal.gov
No package perl(S3::AWSAuthConnection) available.
Error: Nothing to do
Published by jimav on Friday 29 March 2024 01:49
Is there a way to use Path::Tiny to recursively visit directories and files while not aborting completely if an item is inaccessible for some reason?
Specifically, on Windows using Strawberry perl 5.32.1.
AFAICT Path::Tiny's visit
mechanism unconditionally throws an exception if opendir fails, as it is likely to do on various Window-ish system things.
use strict; use warnings;
use Path::Tiny qw/path/;
path(".")->visit(
sub{ print "Visiting $_[0]\n"; }, { recurse => 1 });
print "Done (did not abort)\n";
Running this on Windows (in an Aministrator command window) in the root of C: gives:
Visiting $Recycle.Bin
Visiting $WinREAgent
Visiting BOOTNXT
Visiting bootTel.dat
Visiting Brother
Visiting Jts
...
Error opendir on 'Documents and Settings': Invalid argument at Y:\test.pl line 3.
... and the contents of the folders Brother, Jts, etc. are never visited at all.
Published by Dom Hastings on Friday 29 March 2024 00:56
I've been recently playing around with a Perl answer to a restricted-source code-challenge question on the Code Golf and Coding Challenges stack and am stumped as to why some code that I expect to work, doesn't.
My example is trying to get output from a script when called with -p0513
, but is equivalent:
*_=\"this works!";
print; # outputs `this works!`
*\=\"this doesn't work :(";
print; # outputs `this works!` without `$\`
print$\; # outputs `this doesn't work :(`
I'm wondering why setting *\
to a scalar reference (\"..."
) results in $\
not being correctly print
ed after $_
, when setting it naturally (e.g. $\="test"
) does. $_
being set the same way (e.g. *_=\"test"
) doesn't seem to be affected.
I'm wondering if any Perl experts have any idea why this happens, and if there's a way I can use *\=\"..."
(leaving me a free _
to try and get a 7th output mechanism!)
Published by /u/ReplacementSlight413 on Thursday 28 March 2024 23:32
Some fun with chatgpt (note that you can get the same information with a rudimentary search across various research databases followed by statistical analysis of the tags)
When reading the chat bot response note that
legacy systems include many/most of the research tools in many fields many of the legacy systems are heavily dependent on bash for gluing their individual components many of these legacy systems include a noninsignificant amount for web programming Python / R etc just glue over code written in C and Fortran, ie they just provide an API
Prompt: can you suggest a few application areas for perl as glue in scientific component based software engineering?
Perl can be effectively used as "glue" in scientific component-based software engineering due to its strong text manipulation capabilities, mature ecosystem, and ability to interface with various systems and languages. Here are a few application areas where Perl can excel as a glue language:
Perl has been traditionally strong in bioinformatics, where it is used to connect different software components for tasks like DNA sequence analysis, protein structure prediction, and genetic data processing. It can orchestrate workflows that involve calling various tools, parsing their output, and preparing it for the next step in the analysis pipeline.
In scientific computing, there is often a need to transform data between different formats or integrate data from various sources. Perl can serve as a glue language to script these transformations and integrations, handling formats like CSV, JSON, XML, and proprietary binary formats commonly used in scientific instruments.
Perl can automate and manage tasks in research computing environments, such as scheduling jobs on a compute cluster, monitoring resource usage, and managing file systems. It can glue together various system components, ensuring they work seamlessly to support scientific computation.
Many scientific research fields have legacy software components written in Perl or that provide Perl interfaces. Perl can be used to integrate these components with newer systems, preserving the value of previous investments in software development.
Perl can be used to generate automated reports and visualizations from scientific data. By gluing together data extraction, analysis, and reporting tools, Perl scripts can produce regular, up-to-date reports or visualizations of ongoing scientific research or experiments.
While Perl is useful in these areas, it's essential to consider its limitations. The ecosystem around Perl, particularly in scientific computing, may not be as vibrant as it once was, with many new developments occurring in other languages like Python. Therefore, while Perl remains a powerful tool for certain tasks, its role in new scientific software projects might be more limited compared to its peak usage times.
In conclusion, Perl's role as glue in scientific component-based software engineering is well established, particularly in areas where text processing and legacy system integration are paramount. However, the choice to use Perl should be balanced with considerations about the current and future needs of the project, as well as the availability of skills and community support.
Published by Perl Steering Council on Thursday 28 March 2024 22:51
Discussed some specific ideas for future perl development - more ways to allow CPAN modules to experiment with new ideas, import some possibly-stable ideas from CPAN into core.
Reviewed the list of ongoing experiments in perlexperiment.pod
to work out what can now be declared stable. We’re technically past “user visible changes” freeze but maybe the list will be happy with these changes anyway.
Observed that SSL-in-core still hasn’t made any progress, and wondered further on how we can unstall it and try to get someone working on it eventually. Maybe writing a PPC doc would help?
Published by Brett Estrade on Thursday 28 March 2024 21:31
Talk submissions are still open, and we are seeking proposals on a wide variety of subjects. This includes language features, personal projects, applications like Koha, and anything that may be of general interest to Perl and Raku programmers.
To submit an abstract, please see the authoritative Science Perl CFP or for a standard talk visit the familiar Papercall site.
Please note it is our (the Science Perl Editorial Subcommittee) goal to be able to accept as many perl+science papers and posters as possible, as such our editorial process is designed to be very friendly.
Science Track Deadlines (initial submission is same date/time as the standard talk tracks):
PLEASE SPREAD THE WORD!
Thank you and I am looking forward to some very good things to see in Vegas, baby!
Brett Estrade (OODLER)
Published by /u/leonerduk on Thursday 28 March 2024 17:52
Published by /u/OODLER577 on Thursday 28 March 2024 16:33
Published by cnic023 on Thursday 28 March 2024 11:39
I have created some perl scripts to encrypt and decrypt documents. I do this successfully using openssl 3.0.2. I use openssl enc and -pbkdf2 for greater security keeping my 'password' separate from the encoded data. Unfortunately, I don't have access to linux wherever I am so have tried to use perl module Crypt::CBC but only to decrypt what I have already encrypted with openssl (as I can use Strawberry perl on a MS machine). I want to know if this is even possible, given I don't know exactly how openssl has derived key, vi, salt etc from the plain text password. I keep getting error:
The key must be 128, 192 or 256 bits long at /usr/local/share/perl/5.34.0/Crypt/CBC.pm line 692.
The cipher I am using is aes-256-cbc. This is probably a stupid question (but I am a newb at this).
I expected that, having the password/passphrase used to encrypt, I would be able to decrypt. I am using:
$cipher = Crypt::CBC->new(
-key => $password,
-cipher => "Crypt::OpenSSL::AES",
-pbkdf => 'pbkdf2',
);
Published by Yuki Kimoto - SPVM Author on Thursday 28 March 2024 00:10
How to use OpenMP from Perl with SPVM.
See an example to bind OpenMP to SPVM
SPVM provides a way to bind C language libraries and call them from Perl.
When binding C libraries to Perl, you typically write XS, but SPVM offers an alternative approach.
MyOpenMP.spvm
class MyOpenMP {
native static method sum_vec_int : int[] ($nums1 : int[], $nums2 : int[]);
static method test : void () {
my $nums1 = [1, 2, 3];
my $nums2 = [5, 6, 7];
my $nums3 = &sum_vec_int($nums1, $nums2);
for (my $i = 0; $i < @$nums3; $i++) {
say $nums3->[$i];
}
}
}
MyOpenMP.c
#include "spvm_native.h"
#include <string.h>
static const char* FILE_NAME = "SPVM/MyOpenMP.c";
int32_t SPVM__MyOpenMP__sum_vec_int(SPVM_ENV* env, SPVM_VALUE* stack) {
void* obj_nums1 = stack[0].oval;
if (obj_nums1 == NULL) {
return env->die(env, stack, "$nums1 must be defined.", __func__, FILE_NAME, __LINE__);
}
int32_t* nums1 = env->get_elems_int(env, stack, obj_nums1);
void* obj_nums2 = stack[1].oval;
if(obj_nums2 == NULL) {
return env->die(env, stack, "$nums2 must be defined.", __func__, FILE_NAME, __LINE__);
}
int32_t* nums2 = env->get_elems_int(env, stack, obj_nums2);
int32_t length = env->length(env, stack, obj_nums1);
void* obj_nums3 = env->new_int_array(env, stack, length);
int32_t* nums3 = env->get_elems_int(env, stack, obj_nums3);
int32_t i;
#pragma omp parallel for
for (i = 0; i < length; i++) {
nums3[i] = nums1[i] + nums2[i];
}
stack[0].oval = obj_nums3;
return 0;
}
MyOpenMP.config
use strict;
use warnings;
use SPVM::Builder::Config;
my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);
# Compiler options
$config->add_ccflag('-fopenmp');
# Linker option
$config->add_ldflag('-fopenmp');
$config->add_lib('gomp');
$config;
openmp.pl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/lib";
use SPVM 'MyOpenMP';
SPVM::MyOpenMP->test;
This program outputs values calculated by OpenMP.
6
8
10
Published by laurent_r on Wednesday 27 March 2024 23:33
These are some answers to the Week 262, Task 2, of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Spoiler Alert: This weekly challenge deadline is due in a few days from now (on March 31, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.
You are given an array of integers, @ints
and an integer $k
.
Write a script to return the number of pairs (i, j)
where
a) 0 <= i < j < size of
@ints
b)
ints[i] == ints[j]
c) i x j is divisible by k
Example 1
Input: @ints = (3,1,2,2,2,1,3) and $k = 2
Output: 4
(0, 6) => ints[0] == ints[6] and 0 x 6 is divisible by 2
(2, 3) => ints[2] == ints[3] and 2 x 3 is divisible by 2
(2, 4) => ints[2] == ints[4] and 2 x 4 is divisible by 2
(3, 4) => ints[3] == ints[4] and 3 x 4 is divisible by 2
Example 2
Input: @ints = (1,2,3) and $k = 1
Output: 0
Note that we need to make sure that the input integer $k
is not zero.
We need two nested loops to manage (i, j)
pairs. Property (a) is guaranteed by a proper choice of the ranges for the loop variables. The rest of the program is straight forward.
sub count-equal-div ($divisor where * != 0, @in) {
my $count = 0;
for 0..^@in.end -> $i {
for $i^..@in.end -> $j {
next if @in[$i] != @in[$j];
$count++ if $i * $j %% $divisor;
}
}
return $count;
}
my @tests = (2, (3,1,2,2,2,1,3)), (1, (1,2,3));
for @tests -> @test {
printf "%d - %-15s => ", @test[0], "@test[1]";
say count-equal-div @test[0], @test[1];
}
This program displays the following output:
$ raku ./count-equal-divisible.raku
2 - 3 1 2 2 2 1 3 => 4
1 - 1 2 3 => 0
This is a port to Perl of the above Raku program.
use strict;
use warnings;
use feature 'say';
sub count_equal_div {
my $divisor = shift;
die "$divisor cannot be 0" if $divisor == 0;
my @in = @_;
my $count = 0;
for my $i (0 .. $#in - 1) {
for my $j ($i+1 .. $#in) {
next if $in[$i] != $in[$j];
$count++ if $i * $j % $divisor == 0;
}
}
return $count;
}
my @tests = ( [2, [3,1,2,2,2,1,3]], [1, [1,2,3]] );
for my $test (@tests) {
printf "%d - %-15s => ", $test->[0], "@{$test->[1]}";
say count_equal_div @$test[0], @{$test->[1]};
}
This program displays the following output:
$ perl ./count-equal-divisible.pl
2 - 3 1 2 2 2 1 3 => 4
1 - 1 2 3 => 0
The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on April 7, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
The Perl and Raku Conference (formerly known as YAPC::NA) is going strong! This year, we are celebrating 25 years, our silver anniversary, in the Silver State, Nevada! The main conference will be in Las Vegas on June 25-27, but there will be hackathons and possibly classes on the day before and the day after the conference (June 24th and 28th), so please consider joining us for the whole week!
The backbone of this conference has always been our tracks of "traditional" talks by community members and what we have come to call the "Hallway Track" the informal exchange of ideas and camaraderie that sparks new projects and fuels collaboration.
This year, we are pleased also to host the presentation of Papers and Posters accepted by the Science Perl Journal!
Registration is open, so your ticket can now be purchased.
Talk submissions are still open, and we are seeking proposals on a wide variety of subjects. This includes language features, personal projects, applications like Koha, and anything that may be of general interest to Perl and Raku programmers. (We had juggling and origami in the past. Fun!)
Speakers who are approved for a talk, paper, or poster will receive a free ticket to the event. The submission deadline is April 5th at 8pm EST, so please send us your submissions soon!
We are planning some special activities during the conference to celebrate our rich 25-year history.
Go now to https://tprc.us/ to check out what is planned and to book a room (see link to Alexis Park Resort under "Location"). Rooms start at only $75 per night, so it’s worth booking early!
The best way to register for the conference is at https://tprc2024.sched.com/tickets
Thanks, TPRC Admins
Published by haarg on Tuesday 26 March 2024 21:49
fix core-cpan-diff and sync-with-cpan to handle dist files with v prefixed versions Allow a v prefix on versions expected by the core-cpan-diff and sync-with-cpan scripts. Also align the two scripts with each other, and handle the same file extensions expected by PAUSE.
Ever been staying at a hotel and gotten annoyed that you always have to open a browser to log in for wireless access? Yup, me too. A recent instance was particularly frustrating and I had to pull out my favourite Swiss Army chainsaw in order to make my life a bit easier.
So, the background story is that I was staying at a hotel in the mountains for a few days. As is the fortunate case these days1, the hotel had wireless access. The weird part, though, was that each room had a separate username and password. “Fair enough”, I thought and promptly opened my laptop and then Firefox to enter my login data to get the dearly-awaited connectivity. Using Firefox (or any other browser for that matter) was necessary because the login page was accessed via a captive portal. That’s the thing you get directed through when you see a login banner like this pop up in your browser:
That’s fine, I thought, and went merrily on with my day.
The problem started the following day. After getting up and waking up my laptop, I wasn’t able to read my email2, or read chat on irc3, see my messages via Signal, or use the internet at all4.
Also, ping
greeted me with Destination Net Prohibited
:
$ ping www.heise.de
PING www.heise.de (193.99.144.85) 56(84) bytes of data.
From logout.hotspot.lan (192.168.168.1) icmp_seq=1 Destination Net Prohibited
From logout.hotspot.lan (192.168.168.1) icmp_seq=2 Destination Net Prohibited
From logout.hotspot.lan (192.168.168.1) icmp_seq=3 Destination Net Prohibited
^C
--- www.heise.de ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2002ms
Obviously, I wasn’t online.
That’s when I noticed the Firefox captive portal login banner (see image above) again. Oh, I have to log in again, that’s weird. Upon clicking on the “Open Network Login Page” button, I was logged in automatically. No need to enter the login details again. That’s also weird, I thought, because if the login is automatic, why do I have to visit the login page again at all?
I put my laptop to sleep to go for a walk around the village, get some groceries, and enjoy the mountain air5. Upon my return, I had to log in again to get wireless access. I was slowly starting to get a bit miffed. My guess is that the MAC address from the relevant end-user device is removed from the access list fairly quickly, perhaps on the order of an hour or two6, and thus network connectivity is cut rather promptly.
One issue that made my situation even worse is that I often have several browser windows open at the same time; usually because I have several trains of thought on the go at once and each window contains information relevant to each train of thought. The thing is, only one of the browser windows actually shows the (automatically appearing) captive portal login banner. Finding the window with the banner was rather time consuming.
Ok, this was starting to get silly and a bit annoying. Time to automate the
annoyance away. WWW::Mechanize
to the rescue!
Why choose WWW::Mechanize
? Well, I’ve got experience with it (I used to
use a similar process to automatically log in to the ICE
train in Germany when I
used to commute to work before the
pandemic), I know I can
use it to submit data into simple HTML
forms,
and Perl is my go-to language for this kind of
automation.
So, how to get started with automating the login process? The simple solution: quit Firefox so that all browser windows are closed, put the computer to sleep and then go for a walk for a couple of hours.
Upon my return, I just needed to use a combination of perl -de0
to start a
REPL-like
environment to play around in and perldoc
to read the extensive
WWW::Mechanize
documentation.
The first attempt at trying to trigger a connection to the captive portal didn’t go well:
└> perl -de0
Loading DB routines from perl5db.pl version 1.55
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(-e:1): 0
DB<1> use WWW::Mechanize;
DB<2> $mech = WWW::Mechanize->new;
DB<3> $mech->get('https://google.com');
Error GETing https://google.com: Can't connect to google.com:443 (SSL
connect attempt failed) at (eval
22)[/home/cochrane/perl5/perlbrew/perls/perl-5.30.1/lib/5.30.1/perl5db.pl:738]
line 2.
Ok, so we need to use HTTP and avoid HTTPS. Good to know.
Just using HTTP worked much better:
DB<4> x $mech->get('http://google.com')
0 HTTP::Response=HASH(0x55a95f5048c0)
<snip>
lots of details; you really don't want to see this
</snip>
That’s what we like to see! We’re at least getting stuff back now. Having a look at the page’s title, we get:
DB<5> x $mech->title();
0 'myadvise hotspot > login'
Yup, that’s a login page. Dumping the page’s content with
DB<5> x $mech->content();
<snip>
lots of HTML content
</snip>
we get to see what we’ve got to play with. The main things to note about the content (which I’m not showing because it’s too much detail and I want to protect the innocent) are:
we have a form called login
<form name="login" action="http://login.hotspot.lan/login" method="post">
we have a username field with the name username
<input style="width: 80px" name="username" type="text" value=""/>
and we have a password field with the name password
<input style="width: 80px" name="password" type="password"/>
This gives us enough information to be able to submit the form using the relevant login data.
Aside: interestingly enough, the fields are in English even though the site is a German one. I guess standardising the fields on English can be useful when programming.
To submit the form, we use WWW::Mechanize
’s
submit_form()
method (the call to which I’ve formatted nicely here to make things easier
to read):
$mech->submit_form(
form_name => 'login',
fields => {
username => 'username-for-room',
password => 'password-for-room',
}
);
We can check if the form submission was successful by asking the
HTTP::Response
if things went
well:
DB<7> x $mech->res->is_success;
0 1
Looking good so far. Let’s see if ping
works as expected
$ ping www.heise.de
PING www.heise.de (193.99.144.85) 56(84) bytes of data.
64 bytes from www.heise.de (193.99.144.85): icmp_seq=1 ttl=247 time=20.6 ms
64 bytes from www.heise.de (193.99.144.85): icmp_seq=2 ttl=247 time=13.9 ms
^C
--- www.heise.de ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 13.941/17.281/20.621/3.340 ms
Yes! In other words: we’re in! That was easy. ☺
Putting everything together (and cleaning up the code a bit), I ended up with this:
use strict;
use warnings;
use WWW::Mechanize;
my $mech = WWW::Mechanize->new;
$mech->get('http://google.com');
# check that we have the login page and not Google or something else
# i.e. we're not logged in
if ($mech->title() =~ 'login') {
$mech->submit_form(
form_name => 'login',
fields => {
username => '<username-for-room>',
password => '<password-for-room>'
}
);
if ($mech->res->is_success) {
print "Login successful\n";
}
else {
print "Login failed\n";
}
}
else {
print "Already logged in\n";
}
Now I can just run the script every time I wake my laptop back up and I’m back online. Yay!
From a security perspective it’s a bit weird that the username and password are obviously tied to the room number. In other words, I could probably use the neighbouring room’s account just as easily (I guess: I couldn’t be bothered checking in the end).
Well, this script certainly saved me some time and hassle when waking up my laptop from the suspend state. Also, it was fun working out what pieces of the puzzle were necessary in order to build a solution. Perl saves the day7 again!
Originally posted on https://peateasea.de.
Published by jkeenan on Tuesday 26 March 2024 15:18
For consistency with other DISTRIBUTION entries Use single quotes rather than double. This will facilitate grepping this file.
Published by /u/ruzhnikov on Tuesday 26 March 2024 10:17
Does anybody know what happened with the package Catalyst::Plugin::FormValidator, why it was removed from cpan?
Published by laurent_r on Tuesday 26 March 2024 03:39
These are some answers to the Week 262, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Spoiler Alert: This weekly challenge deadline is due in a few days from now (on March 31, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.
You are given an array of integers, @ints
.
Write a script to return the maximum number of either positive or negative integers in the given array.
Example 1
Input: @ints = (-3, 1, 2, -1, 3, -2, 4)
Output: 4
Count of positive integers: 4
Count of negative integers: 3
Maximum of count of positive and negative integers: 4
Example 2
Input: @ints = (-1, -2, -3, 1)
Output: 3
Count of positive integers: 1
Count of negative integers: 3
Maximum of count of positive and negative integers: 3
Example 3
Input: @ints = (1,2)
Output: 2
Count of positive integers: 2
Count of negative integers: 0
Maximum of count of positive and negative integers: 2
Although this is not clearly specified, we will consider only strictly positive and strictly negative input values (in other words, we will discard values equal to zero).
We use Raku built-in grep, elems, and max methods to come up with a one-liner solution in Raku.
sub max-pos-neg (@in) {
(@in.grep({$_ > 0}).elems, @in.grep({$_ < 0}).elems).max;
}
my @tests = <-3 1 2 -1 3 -2 4>, <-1 -2 -3 1>, <1 2>;
for @tests -> @test {
printf "%-20s => ", "@test[]";
say max-pos-neg @test;
}
This program displays the following output:
$ raku ./max-pos-neg.raku
-3 1 2 -1 3 -2 4 => 4
-1 -2 -3 1 => 3
1 2 => 2
This is a port to Perl of the above Raku program, with the only significant change being that we use the ternary operator (? :
) to replace max
.
use strict;
use warnings;
use feature 'say';
sub max_pos_neg {
my $pos_count = scalar grep {$_ > 0} @_;
my $neg_count = scalar grep {$_ < 0} @_;
$pos_count > $neg_count ? $pos_count : $neg_count;
}
my @tests = ( [<-3 1 2 -1 3 -2 4>],
[<-1 -2 -3 1>], [<1 2>] );
for my $test (@tests) {
printf "%-20s => ", "@$test";
say max_pos_neg @$test;
}
This program displays the following output:
$ perl ./max-pos-neg.pl
-3 1 2 -1 3 -2 4 => 4
-1 -2 -3 1 => 3
1 2 => 2
The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on April 7, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Photo © Salve J. Nilsen, 2023, CC-BY-NC-4.0
TL;DR Please read and share the prospectus for the Perl Toolchain Summit.
It’s that time of year again. In a few weeks, dozens of Perl hackers will be meeting in Lisbon, Portugal to hack furiously on the Perl Toolchain. I will be there as well, working on MetaCPAN. Most of the other core MetaCPAN developers will be there as well, as is the case most years. We get lots of work done. I usually blog about it. To get an idea of what goes on, you can check out my 2023 Perl Toolchain Summit report and Salve J. Nilsen’s photos.
The summit is a great opportunity for your company to get involved and support the Perl community. Here are 5 reasons why you should sponsor the Perl Toolchain Summit.
The developers who maintain CPAN and its associated tools and service are scattered all across the globe and, more importantly, in different time zones. Most of us know that it’s entirely possible to get things done at our day jobs while working remotely. It’s not always this easy when trying to co-ordinate the time, efforts and schedules of volunteers. The Perl Toolchain Summit is the only time of the year when most of these developers are in the same room together. The event gives them the luxury of synchronous, rather than asynchronous communication. Imagine walking across the room to talk to someone rather than waiting for someone who lives across an ocean to find the free time to respond to a GitHub issue or a chat message. Problems can be solved much faster when you get so many stakeholders and decision makers in the same room.
We also know that communication can be hard and it doesn’t necessarily get easier when much of it happens by text. Giving the Toolchain developers the chance to work face to face means they have a greater understanding and appreciation of whom they are dealing with. The cameraderie which develops at this event allows the Toolchain developers to communicate freely and well when they’re not all together. I’m amazed at how well everyone gets along for the part of the year when we’re not in the same room. It’s a very special group of people.
Some big decisions require consensus. Consensus requires getting input from many people. Being able to call a meeting to discuss topic X with all of the relevant people is kind of a big deal. Past toolchain summits have given us documents which offer a guide on how to move forward. The Lancaster Consensus is such a document.
Most Open Source developers are juggling a bunch of things in their day to day lives and hacking on software is just one of those things. Many of us rarely get more than a few hours in a given week to work distraction-free on something which interests us. Sometimes we don’t even have that luxury. The Toolchain summit gives developers 3-4 days of time to keep barreling ahead on critical software. Imagine what you could do with a hobby project when all you had to worry about was getting up in the morning, having a prepared meal and then plugging in your laptop and consulting the experts sitting around you? That’s exactly what this event is like. It also has the side effect of increasing the cadence of a project in the weeks leading up to the Toolchain where everyone prepares ahead of time, in order to maximize their creativity upon arrival.
The Perl Toolchain Summit works to ensure that the parts of the Perl Ecosystem which developers (and businesses) around the world rely on, are cared for. Some problems are thorny. They require time. They require expertise. They require help and possibly a shoulder to cry on. If your business relies on Perl, then it relies on the toolchain. It relies on a healthy and secure ecosystem. These are critical things, but they’re also boring. They’re not flashy new apps. They’re not going to get you on the front page of Hacker News. They are, however, going to allow people and businesses around the world to carry on with their lives, blissfully unaware of the efforts which are going into the software which underpins some part of their existence. Sponsoring this event allows you to support the boring, important parts of Perl.
By now you’re probably thinking “shut up and take my money”. That’s wonderful! Sponsoring the event is easy. Please have a look at the prospectus. It has more information on this event and it has everything you need to get started as a sponsor. Kindly pass the prospectus along to your friends and colleagues and together we can work together to keep the Perl Toolchain moving forward.
Published on Monday 25 March 2024 17:11
Some app I work on needs to export some data and send it to customers in a traceable way. We need to make sure that we keep track of each filename, and also make sure that the customers can (maybe even months later) tell us which export file might need some handling. So we decided to use a rather verbose filename containing the customer name, a timestamp and the uuid of the export job eg export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c8e871.zip
.
Generating and sending such a mail is quite easy using eg Email::Stuffer and Email::Sender::Simple:
my $filename = 'export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c8e871.zip';
my $email = Email::Stuffer
->to( $customer_email )
->cc( $our_archive_email )
->from( $sender )
->subject( "Your data" )
->text_body( "Please find your data attached" )
->attach_file( $filename )
->email;
Email::Sender::Simple->send( $email, { transport => $smtp } );
I tested this using a local maildev and also via google mail (as we're using that for that project..). It also worked for the customers. Well, some customers...
One customer complained that they could not open the file (on Windows). The file actually is a password "protected" zip archive containing a CSV, so I assumed they had some problems with that setup and provided some detailed instruction on how to open / extract that file and make sure that Windows does not mangle the extensions etc. The customer was satisfied. I grumbled a bit about Windows and customers and went on to do other stuff.
Some time later, due to some stupidity on my part, we sent out that file as a regular CSV file (without packing it into zip). Again, the customer complained that they could not unpack the file after downloading it and adding a zip
extension. That's when I started to wonder what was really going on, because I got the mail as a plain CSV file and never should the customer need to manually add an extension.
And what going on was that the customer did not get any file extensions, just a plain string, then manually added the (in that case wrong) extension zip
and only then could proceed. And the customer was not using gmail, but something else.
So I tried to open the mail in mutt, and .. the attachment was indeed mangled: The filename was truncated, the extension missing.
This prompted a closer examination of the mail headers:
Content-Type: application/octet-stream;
name*0=export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c8;
name*1=e871.zip
name=export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c...
Ouch!
It seems that some part of the (40 years old?) email spec cannot handle long filenames, therefore they are broken into multiple lines.
And it seems that some mail clients can handle this multi line filenames, and some cannot handle them (among them mutt, which I find sad, but in this case lucky, because I'm not sure I would ever found the real bug and just assumed customer incompetence...)
The fix was of course easy: pack the actual file (with the still long and very verbose filename) into a zip archive with a different, much shorter name.
But it was still interesting to learn that in that case the problem was not a stupid customer or an annoying OS, but the fact the email obviously needs to printable on a dot-matrix printer and therefor should not have more than 80 characters per line...
Update: dakkar pointed out the relevant RFC 2332, Section 3.
Published by Gabor Szabo on Monday 25 March 2024 09:30
Originally published at Perl Weekly 661
Hi there!
Perl 5.39.9 was released including the new ^^ operator. It is only a development release, but I'd like to encourage you to give it a try and give feedback to the developers.
There was some nefarious activity on CPAN. Someone re-uploaded perl-5-38.2. It was reported and the security team quickly eliminated the threat.
I was wondering if I should write about the hate mails I received: one for myself as Jew (my ethnicity) triggered by what I wrote two weeks ago and one on behalf of Mohammed as a Muslim (his religion) triggered by what he wrote last week. I've removed these people from the distribution, but I think they need more accountability. I am still contemplating publishing the names of these people along with their messages so the Perl community and their employers will be aware of that. After all most of us don't want to work with abusive people, do we?
The Perl Toolchain Summit is coming again and they need your help sponsoring the even. Here is the Sponsor prospectus for Perl Toolchain Summit 2024. Last year I ran an online course about Open Source development and the proceedings went to the summit (though I transferred them late, so probably they could not use that in time). This year I don't have the time for that, but I hope you will see the value in the summit and will sponsor it directly.
Enjoy your week!
--
Your editor: Gabor Szabo.
With the new ^^ logical xor operator. And a reminder: it is a development release.
Roles are used when you need to share behaviour among several classes that don’t have to be related by inheritance. Normally, a role just adds a bunch of methods to the class that consumes it (there’s more, you can for example specify which other methods the role expects to already exist). A parameterized role makes it possible to provide parameters for the consumed role. This way, you can adjust the behaviour for each consuming class.
The Weekly Challenge by Mohammad Sajid Anwar will help you step out of your comfort-zone. We pick one champion at the end of the month from among all of the contributors during the month.
Welcome to a new week with a couple of fun tasks "Max Positive Negative" and "Count Equal Divisible". If you are new to the weekly challenge then why not join us and have fun every week. For more information, please read the FAQ.
Enjoy a quick recap of last week's contributions by Team PWC dealing with the "Element Digit Sum" and "Multiply by Two" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.
Using pack() then unpack() to get the element sum. This is something very handy. Find out more in the post.
Lots of Raku magic, '>>.comb' and '>>.sum' can be lethal. Keep it up great work.
Using CPAN module makes it compact and elegant. Did you know that 261 is an Odious Number? Well done.
This week task was ideal for Raku one-liner and here we have one, incredible.
Pure mathematical approach with the help of CPAN module. Don't you love the one-liner it generates? Really cool.
Comparative solutions in Perl and Raku can be fun. Plenty to learn just following the code.
Using Bag in Raku is an ideal choice, something any Perl dev can relate to. Thanks for sharing.
Being master of Raku one-liner, we have yet another cute one-liner, you don't want to skip it.
Master of Perl one-liner is at his best. You don't want to miss it. Highly recommended.
Simple yet elegant solutions in Perl. Task analysis is not to be missed though.
Clever use of Raku's Reduction Metaoperator makes it ideal to get the job done. CPAN has an alternative to the Raku's counterpart. Well done.
Lack of clarity in task description handled very well. Task analysis is always fun to read.
CPAN module can make your life fun and easy. You must checkout the solutions.
You will love how Set of Raku can be fit for the job. Thanks for sharing knowledge with us.
Near identical solutions in Perl and Python. No wonder Python is second choice for all Perl programmer.
Great CPAN modules released last week.
You joined the Perl Weekly to get weekly e-mails about the Perl programming language and related topics.
Want to see more? See the archives of all the issues.
Not yet subscribed to the newsletter? Join us free of charge!
(C) Copyright Gabor Szabo
The articles are copyright the respective authors.
Published by tonycoz on Sunday 24 March 2024 22:25
perldelta for a2b66c25985f, save PL_comppad safely
Published by tonycoz on Sunday 24 March 2024 22:11
prepare_export_lexical: save PL_comppad safely When the pad being saved and the pad for PL_compcv is the same, in some cases the actual exports would result in reallocating the AvARRAY() for the saved PL_comppad. The LEAVE in finish_export_lexical() would restore the old PL_comppad (which is fine) and the pre-reallocation PL_curpad (which isn't fine). This would later panic. SAVECOMPPAD; restores PL_comppad on LEAVE and then restores PL_curpad from PL_comppad, preventing the desync between those values. It's unclear to me why only the save_BEGINs; causes this, but the fix does fix a real problem and prevents the panics that I'm aware of here. Fixes #21981
Published by tonycoz on Sunday 24 March 2024 22:08
Revert "testsuite.yml: fix ASAN build tests" This reverts commit d1971b5f57c5a31b1d61d7b2e5816942d69ed954. ctions/runner-images#9491 has been fixed.
Published by Unknown on Sunday 24 March 2024 15:59
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
You are given an array of integers, @ints
.
Write a script to evaluate the absolute difference between element and digit sum of the given array.
Given that Perl doesn't care (most of the time) between numbers and strings, this is one of those challenges that is easier to do in Perl.
my $element_sum = sum(@ints);
my $digit_sum = sum( map { split // } @ints );
say abs( $element_sum - $digit_sum );
The sum function comes from List::Util. The first line gets the sum of the elements. The second line splits the integers by the digits and calculates the sum. The final line calculates and display the absolute difference.
My Python solution is as follows
def element_digit_sum(ints: list) -> int:
element_sum = sum(ints)
digit_sum = sum(int(i) for s in map(str, ints) for i in s)
return abs(element_sum - digit_sum)
It follows the same logic and the Perl code. The second line does the following
map(str, ints)
turns the list of integers into a generator of stringsfor s in
iterates over the generatorfor i in s
iterates over each character in the stringint(i)
turns that character into an integersum()
turns the list of integers into a sum of the values$ ./ch-1.py 1 2 3 45
36
$ ./ch-1.py 1 12 3
9
$ ./ch-1.py 1 2 3 4
0
$ ./ch-1.py 236 416 336 350
1296
You are given an array of integers, @ints
and an integer $start..
Write a script to do the following:
@ints
, if found multiply the number by 2In the end return the final value.
This seems relatively straight forward. I keep multiplying the start
by two until the value does not appear in the list. For performance, I could have converted the list into a set (hash in Perl), as checking in-ness (is that a word?) is faster that way. However, we are dealing with a small list, so it is not required.
def multiple_by_two(ints: list, start: int) -> int:
solution = start
while solution in ints:
solution *= 2
return solution
$ ./ch-2.py 5 3 6 1 12 3
24
$ ./ch-2.py 1 2 4 3 1
8
$ ./ch-2.py 5 6 7 2
2
Published on Saturday 23 March 2024 20:34
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
You are given an array of integers, @integers. Write a script to evaluate the absolute difference between every element and the digit sum of the entire given array.
The complete solution is contained in one file that has a simple structure.
For this problem we do not need to include very much. We’re just specifying to use the current version of Perl, for all the latest features in the language. This fragment is also used in Part 2.
First, let’s consider how we compute the digit sum for an array of integers. If we we make sure that all multi-digit numbers are expanded into lists of digits then this is the sum of the concatenation of all such lists, along with single digit numbers.
The expansion of multi-digit numbers is handled by map, and the sum is taken with unpack and the resulting final array. A key thing to remember here is that Perl will flatten all lists inside the array so all the results from the map will be in a list of single digits.
The element sum is the same procedure as the digit sum, but just without the map.
Finally, we have a few lines of code for running some tests.
MAIN:{
say element_digit_sum 1, 2, 3, 45;
say element_digit_sum 1, 12, 3;
say element_digit_sum 1, 2, 3, 4;
say element_digit_sum 236, 416, 336, 350;
}
◇
Fragment referenced in 1.
$ perl perl/ch-1.pl 36 9 0 1296
You are given an array of integers, @integers and an integer $start. Write a script to do the following:
a) Look for $start in the array @integers, if found multiply the number by 2.
b) If not found stop the process, otherwise repeat.
In the end return the final value.
We’ll contain the solution in a single recursive function. The completed solution will just have that function plus a few tests.
This is our principal function. As can be seen, it’s very short! The logic here is simple: for each recursive call check for $start in the array and, if found, double $start and keep recursing. Otherwise, return $start.
sub search_multiply{
my($start) = shift;
return $start if 0 == grep {$start == $_}
@_;
search_multiply($start + $start,
@_);
}
◇
Fragment referenced in 7.
Finally, here’s a few tests to confirm everything is working right.
MAIN:{
say search_multiply 3, 5, 3, 6, 1, 12;
say search_multiply 1, 1, 2, 3, 4;
say search_multiply 2, 5, 6, 7;
}
◇
Fragment referenced in 7.
$ perl ch-2.pl 24 8 2
Published by Perl Steering Council on Thursday 21 March 2024 23:01
This week, we:
Published by Gabor Szabo on Monday 18 March 2024 05:43
Originally published at Perl Weekly 660
Hi there,
Happy Ramadan to all the readers who fast during this holy month. May ALLAH s.w.t accept your fasting, Ameen.
I recently became active on official Slack for The Perl Foundation after a long gap. I noticed it is very much active and live. Lots of positive noise and useful information shared with each other. I am not a big fan of Slack but after spending just few days, I find it easy to move around. I would like to keep an eye for important news and announcement. Earlier my only source of information was the good old https://blogs.perl.org. We used to have regular post by Perl enthusiasts but that has stopped unfortunately. And I don't blame them as I also stopped blogging completely. As and when I do blog, I use The Weekly Challenge platform. Having said, the platform is still used by some, for example Perl Steering Council for weekly updates. Every now and then, you do get some magical post by Perl fans. One such post, Changes in MooX::Role::Parameterized appeared last week by E. Choroba. I have been a big fan of Moo - Minimalist Object Orientation, so this post became even more important for me. Although, Corinna has made it to the Perl core, it is still a long way before it becomes a complete solution to all OO needs. I am looking forward to the next big release which would bring in some more features, hopefully.
What's new on CPAN?
I was introduced to perl.com by the post series What's new on CPAN? by David Farrell. It used to be regular every month with full of fun facts about new CPAN modules released. During those days, I used to be active on CPAN and released few CPAN. I had the honour to find place in the post often. Recently Olaf Alders took the initiative to revive the activities on perl.com. Because of his hard work and with the help of Mathew Korica we now have the post series back. You must check latest in the series, What's new on CPAN - February 2024.
I just realised that this is my 150th edition and in 2 months I will complete 6 years as co-editor of the Perl Weekly newsletter. It has been a very fruitful learning experience for me and I enjoyed it thoroughly.
Keep the spirit high and don't let the bad influence pull you down. Please do take care your health and loved ones.
--
Your editor: Mohammad Sajid Anwar.
Time has come to start preparing for the next big event. Please reserve your place as soon as you can.
Teaming with the french mongers, Open Food Facts organize a Hackathon around the use of Perl by it's web server which is the heart of the project. It will take place in Paris, on Saturday March 23 and Sunday March 24. Remote participation is possible.
It is so pleasing to see my favourite series is back. Thank you the entire team behind this, you guys are doing a great service to keep this alive.
Another week another update by the super charged Perl Steering Council.
For all Moo users, this is for you if you have worked with Roles. This change would make your life easy. Enjoy !!
Perl API client for Intellexer by Joshua Day, his first contribution to CPAN and hope not the last.
Grant report for the work carried out by Tony Cook.
The Weekly Challenge by Mohammad Sajid Anwar will help you step out of your comfort-zone. We pick one champion at the end of the month from all of the contributors during the month.
Welcome to a new week with a couple of fun tasks: "Element Digit Sum" and "Multiply by Two". If you are new to the weekly challenge, why not join us and have fun every week? For more information, please read the FAQ.
Enjoy a quick recap of last week's contributions by Team PWC dealing with the "Unique Occurrences" and "Dictionary Rank" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.
Adam's use of do { ... } for .. always fascinates me. Mind you this is happening alongside the latest Perl v5.38.
Solution to dictionary rank blown me away. You must checkout his creative innovation.
As always Raku is showing off with the help powerful feature of Bag. Keep it up great work.
Have you played with BQN? If not then you should as it is not just another programming language. Check out the post yourself.
Task analysis by Dace is unmatched. I just simply love the way he deals with challenge. Keep it up.
Raku is presenting mathod chaining once again. It is one of my favourite. How about you?
Explore the mathematical view of the dictionay rank task. You may find it too complex but it is always fun.
Raku one-liner is showing the elegance. Raku Rocks !!
Using CPAN and still getting one-liner in Perl, incredible. Keep us entertained every week.
We have seen how CPAN cam be handy is dealing with challenges. This week too, we saw the evidence.
I see Raku code written in Perl style. It tells Packy is a diehard Perl fan. Thank you for your contributions.
Just a simple and straight forward approach, anyone can easily follow. Well done and keep it up.
For permuation related challenge, Math::Combinatorics is one of the choices CPAN provides. See the post how this solved the task.
Unlike others Roger used Set of Raku language to deal with the challenge this week. In addition we got PostScript solution discussed too. Highly recommended.
Python is my new crush and everytime I read post about Python solution, it feels nice to be able to follow through. The use of defaultdic is one of them. Thanks for sharing.
Great CPAN modules released last week;
MetaCPAN weekly report;
StackOverflow Perl report.
You joined the Perl Weekly to get weekly e-mails about the Perl programming language and related topics.
Want to see more? See the archives of all the issues.
Not yet subscribed to the newsletter? Join us free of charge!
(C) Copyright Gabor Szabo
The articles are copyright the respective authors.
Published by Unknown on Sunday 17 March 2024 09:30
Published by Unknown on Sunday 17 March 2024 09:27
This is the weekly favourites list of CPAN distributions. Votes count: 33
Week's winners (+3): Spreadsheet::ParseExcel
Build date: 2024/03/17 08:26:48 GMT
Clicked for first time:
Increasing its reputation:
These are the five most rated questions at Stack Overflow last week.
Between brackets: [question score / answers count]
Build date: 2024-03-17 08:25:15 GMT
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
You are given an array of integers, @ints
.
Write a script to return 1
if the number of occurrences of each value in the given array is unique or 0
otherwise.
For this task I start by calculating the frequency of each integer, and store this in a dict (hash in Perl) called freq
.
def uniq_occurrences(ints: list) -> bool:
freq = defaultdict(int)
for i in ints:
freq[i] += 1
I then loop through the values of the dict (the frequency). If I have seen this frequency before, we know it is not unique, and can return False. If I haven't seen it, I add it to the seen
dict in case we see it again.
Once I have looped through all values, I return True to indicate the occurrences are unique.
seen = {}
for i in freq.values():
if i in seen:
return False
seen[i] = 1
The second part definitely fails under TMTOWTDI. One possible alternate solution is len(freq) == len(set(freq.values())
. While probably quicker, it's not as straight forward to understand.
$ ./ch-1.py 1 2 2 1 1 3
1
$ ./ch-1.py 1 2 3
0
$ ./ch-1.py -2 0 1 -2 1 1 0 1 -2 9
1
You are given a word, $word
.
Write a script to compute the dictionary rank of the given word.
This task was a little more challenging than a first thought, and more so for the Perl solution. This is because while I can calculate all the permutations of letters easily, I only want to count unique permutations. For example, the word baa
has 3! (6) permutations, but only 3 are unique (aab
, aba
, baa
).
Thankfully there is a distinct_permutations method in more_itertools that makes this easy.
The first thing I do is convert the word into lower case and convert it into a tuple. I store this as the variable tuple_word
.
I then sort the tuple alphabetically and store this as letters
and parse it to the distinct_permutations
generator. I keep counting until I find the tuple that has the original word.
def dictionary_rank(word: str) -> int:
tuple_word = tuple(word.lower())
letters = sorted(tuple_word)
count = 0
for perm in distinct_permutations(letters):
count += 1
if perm == tuple_word:
break
return count
It should be noted that the performance of the solutions are really only good if it appears early (alphabetically) or has less than 11 characters. Calculating the rank of 'kjihgfedcba' took 35 seconds on my PC. For the record it is ranked 39,916,800th which is also 11!.
The Perl solution is slightly different. My go to for permutations in Perl is usually Algorithm::Combinatorics, but this doesn't have a function for distinct permutations. Math::Combinatorics does, however the order of them is not guaranteed.
For the task, I count all unique permutations that are less than or equal to the word, and print that.
$ ./ch-2.py CAT
3
$ ./ch-2.py GOOGLE
88
$ ./ch-2.py SECRET
255
Published on Saturday 16 March 2024 20:39
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
You are given an array of integers, @ints. Write a script to return 1 if the number of occurrences of each value in the given array is unique or 0 otherwise.
The complete solution is contained in one file that has a simple structure.
For this problem we do not need to include very much. We’re specifying to use the current version of Perl, for all the latest features. We’re also using the boolean module, for the convenience of returning and displaying the return values.
This fragment is also used in Part 2.
Here we have a single function which does essentially all the work. First we loop through the array of numbers and count occurrences. Then the counts are themselves used as hash keys to eliminate duplicates. If no duplicates are removed then the number of these new keys is equal to the number of original count values.
sub unique_occurrences{
my %occurrences;
do{
$occurrences{$_}++;
} for
@_;
my %h;
do{$h{$_} = undef} for values %occurrences;
return boolean(values %occurrences == keys %h);
}
◇
Fragment referenced in 1.
Finally, we have a few lines of code for running some tests.
MAIN:{
say unique_occurrences 1, 2, 2, 1, 1, 3;
say unique_occurrences 1, 2, 3;
say unique_occurrences -2, 0, 1, -2, 1, 1, 0, 1, -2, 9;
}
◇
Fragment referenced in 1.
$ perl perl/ch-1.pl 1 0 1
You are given a word, $word. Write a script to compute the dictionary rank of the given word.
The solution to the second part of this week’s challenge is a little more complex than the first part. In the solution file we define our own function for computing all permutations of an array, which is then used to determine the dictionary rank.
This function is a recursive implementation of Heap’s algorithm. A lot has been written on this algorithm, so I won’t go into much detail here.
sub permutations{
my($a, $k, $permutations) =
@_;
if($k == 1){
push
@{$permutations}, [
@{$a}];
return true;
}
else{
permutations($a, $k - 1, $permutations);
for my $i (0 .. $k - 2){
if($k & 1){
($a->[0], $a->[$k - 1]) = ($a->[$k - 1], $a->[0]);
}
else{
($a->[$i], $a->[$k - 1]) = ($a->[$k - 1], $a->[$i]);
}
permutations($a, $k - 1, $permutations);
}
}
}
◇
Fragment referenced in 5.
Now that we have a way to compute all permutations we will use that to determine the dictionary rank. There is a trick here. Keep in mind that dictionaries do not have multiple entries for repeated words! In the case of words with repeated letters than there will be permutations that are effectively equal in that they contain the same letters. Although they are created by permuting equal (but different) letters for ranking purposes we will consider them the same.
sub dictionary_rank{
my($word) =
@_;
my $permutations = [];
permutations [split //, $word], length($word), $permutations;
my %h;
do {$h{join q//,
@{$_}} = undef} for
@{$permutations};
my
@permutations = sort {$a cmp $b} keys %h;
return (
grep {$permutations[$_] eq $word} 0 ..
@permutations - 1
)[0] + 1;
}
◇
Fragment referenced in 5.
MAIN:{
say dictionary_rank q/CAT/;
say dictionary_rank q/GOOGLE/;
say dictionary_rank q/SECRET/;
}
◇
Fragment referenced in 5.
$ perl ch-2.pl 3 88 255
Published by Todd Rinaldo on Friday 15 March 2024 23:13
The Perl and Raku Conference (formerly knwn as YAPC::NA) is going strong! This year, we are celebrating 25 years, our silver anniversary, in the Silver State, Nevada! The main conference will be in Las Vegas on June 25-27, but there will be hackathons and possibly classes on the day before and the day after the conference (June 24th and 28th), so please consider joining us for the whole week!
The backbone of this conference has always been our tracks of "traditional" talks by community members and what we have come to call the "Hallway Track" the informal exchange of ideas and camaraderie that sparks new projects and fuels collaboration.
This year, we are pleased also to host the presentation of Papers and Posters accepted by the Science Perl Journal!
Registration is open, so your ticket can now be purchased.
Talk submissions are still open, and we are seeking proposals on a wide variety of subjects. This includes language features, personal projects, applications like Koha, and anything that may be of general interest to Perl and Raku programmers. (We had juggling and origami in the past. Fun!) * Talks can be 20 minutes or 50 minutes. Please submit through PaperCall. * Papers and Posters follow the guidelines of the Science Perl Journal. Links to both are also on https://tprc.us.
Speakers who are approved for a talk, paper, or poster will receive a free ticket to the event. The submission deadline is April 5th at 8pm EST, so please send us your submissions soon!
We are planning some special activities during the conference to celebrate our rich 25-year history.
Go now to https://tprc.us/ to check out what is planned and to book a room (see link to Alexis Park Resort under "Location"). Rooms start at only $75 per night, so it’s worth booking early!
The best way to register for the conference is at https://tprc2024.sched.com/tickets
Thanks, TPRC Admins
Welcome to “What’s new on CPAN”, a curated look at last month’s new CPAN uploads for your reading and programming pleasure. Enjoy!
Published by Spontaneous21 on Tuesday 12 March 2024 10:34
Perl, a high-level, interpreted programming language, has been a stalwart in the world of computer science since its inception in the late…
Published by alh on Monday 11 March 2024 08:10
Tony writes:
``` [Hours] [Activity] 2023/12/04 Monday 0.42 #21677 minor fix. testing 0.23 #21661 check smoke results, minor commit message edit, make PR 21683 1.90 #21680 testing, debugging 1.28 #21680 fixes, testing, push for CI 1.42 #21651 testing and reproduce, try a fix and testing, push
5.25
2023/12/05 Tuesday 0.30 #21677 research 0.95 #21664 apply to blead, perldelta, comment on original perlmonks post 0.82 #13814 research 0.38 #13814 try a different approach
3.07
2023/12/06 Wednesday 1.07 #13814 review CI results, documentation, testing, make PR 21693 2.48 #21692 review, comments, try to work out getlines() cleanup 1.52 #21692 finally figure it out, comment 0.13 #21686 testing and comment 0.57 #16535 research and close 0.12 #16529 research and close
5.97
2023/12/07 Thursday 0.38 #17457 rebase, retest, push for CI 2.03 #17435 testing, work on a fix, more testing 0.35 #21679 apply to blead, perldelta 0.75 #13814 changes per comments
3.61
2023/12/08 Friday 0.35 #21696 apply to blead, update dist/IO/Changes
0.60
2023/12/11 Monday 0.20 #21684 follow-up 0.72 #21701 research and comment 0.63 #21705 research and comment 0.60 #21702 testing, research and approve 0.08 #21706 review and approve 0.13 #21703 review and approve 0.08 #21699 review and approve 0.08 #21698 review and approve 0.08 #21704 review and approve 0.17 #21700 review and approve 1.03 #21701 testing, research, comment 0.13 #21708 review and approve
4.08
2023/12/12 Tuesday 1.02 #21712 review the code, testing, comment (not a bug) 0.68 #21684 apply to blead, look at regenning the deps
1.93
2023/12/13 Wednesday 0.27 #21705 research and comment 0.22 #21710 review and approve 2.38 #21714 review and approve, comment 0.27 #21711 review and approve 0.18 #21713 review and approve 0.40 #21676 review and approve
6.14
2023/12/14 Thursday 0.12 #21714 follow-up 1.83 #21701 testing and research, comment
2.58
2023/12/18 Monday 0.42 #21725 debugging, comment 1.38 #21716 debugging. research, comment, work on a fix, push
1.80
2023/12/19 Tuesday 1.08 #21716 minor fixes, testing and comments 0.62 #21725 add comment 0.85 #21719 review, research and comments
2.87
2023/12/20 Wednesday 0.45 #21723 review, research and approve 0.18 #21726 review, research (alternate openbsd libc anywhere?, apparently not), approve 0.23 #21728 review and approve 0.58 #21720 review, comments and approve 0.25 #21731 follow-up comment 0.70 #21636 re-work 1.03 #21636 more re-work, testing and push 0.50 #21732 testing and comment, work on fixing the most
3.92
2023/12/21 Thursday 0.08 #21732 review discussion, check CI results and create PR 21737 0.20 #21716 review discussion and comment 0.15 #21719 review updates and approve
1.48
Which I calculate is 43.3 hours.
Approximately 44 tickets were reviewed or worked on, and 5 patches were applied. ```
Published on Sunday 10 March 2024 23:41
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
You are given a start date and offset counter. Optionally you also get bank holiday date list. Given a number (of days) and a start date, return the number (of days) adjusted to take into account non-banking days. In other words: convert a banking day offset to a calendar day offset.
Non-banking days are:
Using Time::Piece the work can be contained in a single function. Really the main piece of logic required of sub count_days() is for us to check if a day is a weekend or bank holiday.
sub count_days{
my($start, $offset, $holidays) =
@_;
$start = Time::Piece->strptime($start, q/%Y-%m-%d/);
my $t = $start;
my $end = $start;
{
$t += ONE_DAY;
unless(
⟨The day is a weekend. 2 ⟩ ||
⟨The day is a bank holiday. 3 ⟩){
$end = $t;
$offset--;
}
redo if $offset > 0;
}
return $end->strftime(q/%Y-%m-%d/);
}
◇
Fragment referenced in 4.
1 == grep {$t->strftime(q/%Y-%m-%d/) eq $_}
@{$holidays}
◇
Fragment referenced in 1.
The rest of the code just tests this function.
MAIN:{
say count_days q/2018-06-28/, 3, [q/2018-07-03/];
say count_days q/2018-06-28/, 3;
}
◇
Fragment referenced in 4.
$ perl perl/ch-1.pl 2018-07-04 2018-07-03
You are given a line like below:
{% id field1=“value1”field2=“value2”field3=42 %}
Where
The line parser should return a structure like:
{ name => id, fields => { field1 => value1, field2 => value2, field3 => value3, } }
It should be able to parse the following edge cases too:
{% youtube title="Title␣\"quoted\"␣done" %}
and
{% youtube title="Title␣with␣escaped␣backslash␣\\" %}
Most of the work is done in a parser constructed using Parse::Yapp.
First off, before we get into the parser, here is a small bit of code for driving the tests.
sub print_record{
my($record) =
@_;
say q/{/;
say qq/\tname => / . $record->{name};
say qq/\tfields => {/;
for my $field (sort {$a cmp $b} keys %{$record->{fields}}){
say qq/\t\t$field => / . q/ / . $record->{fields}->{$field};
}
say qq/\t}/;
say q/}/;
}
◇
Fragment referenced in 8.
The rest of the code drives some tests.
use v5.38;
use Ch2;
use constant TEST0 => q/{% id field1="value1" field2="value2" field3=42 %}/;
use constant TEST1 => q/{% youtube title="Title␣\"quoted\"␣done" %}/;
use constant TEST2 => q/{% youtube title="Title␣with␣escaped␣backslash␣\\\\" %}/;
◇
Fragment referenced in 8.
MAIN:{
my $parser = Ch2->new();
say TEST0;
print_record($parser->parse(TEST0));
say TEST1;
print_record($parser->parse(TEST1));
say TEST2;
print_record($parser->parse(TEST2));
}
◇
Fragment referenced in 8.
Here is where the work is really done. Parse::Yapp is given the following grammar. A parser is generated, contained in it’s own module.
First off is the grammar’s header. Here we define the symbols used in the rules which follow. We also add a small code block which contains a hash for holding the structure obtained from the parsed text.
%token NUMBER
%token START
%token END
%token WORD
%token QUOTE
%token ESCAPED_QUOTE
%{
my %record = (fields => {});
%}
◇
Fragment referenced in 17.
Here is the most important section, the rules for processing the input! For some rules we have also added action code blocks. We want to construct a data structure from the given input and in these action code blocks that final result is accumulated. Remember, the first rule is going to be called last, when the input is complete, so there we give a reference to a hash containing the result. This is the return value for the parse function found in the grammar’s footer.
file: START id fields END {$record{name} = $_[2]; \%record;}
;
id: WORD
;
words: WORD
| words WORD
| words ESCAPED_QUOTE WORD ESCAPED_QUOTE
;
field: WORD ’=’ NUMBER {$record{fields}->{$_[1]} = $_[3]}
| WORD ’=’ QUOTE words QUOTE {$record{fields}->{$_[1]} = $_[4]}
;
fields: field
| fields field
;
◇
Fragment referenced in 17.
The footer contains additional Perl code for the lexer, error handing, and a parse function which provides the main point of execution from code that wants to call the parser that has been generated from the grammar.
The lexer function is called repeatedly for the entire input. Regular expressions are used to identify symbols (the ones declared in the header) and pass them along for the rules processing.
sub lexer{
my($parser) =
@_;
$parser->YYData->{INPUT} or return(’’, undef);
$parser->YYData->{INPUT} =~ s/^[ \t]//g;
##
# send tokens to parser
##
for($parser->YYData->{INPUT}){
s/^([0-9]+)// and return ("NUMBER", $1);
s/^({%)// and return ("START", $1);
s/^(%})// and return ("END", $1);
s/^(\w+)// and return ("WORD", $1);
s/^(=)// and return ("=", $1);
s/^(")//␣and␣return␣("QUOTE",␣$1);
s/^(\\")//␣and␣return␣("ESCAPED_QUOTE",␣$1);
s/^(\\\\)// and return ("WORD", $1);
}
}
◇
Fragment referenced in 16.
The parse function is for the convenience of calling the generated parser from other code. yapp will generate a module and this will be the module’s method used by other code to execute the parser against a given input.
Notice here that we are squashing white space, both tabs and spaces, using tr. This reduces all repeated tabs and spaces to a single one. The eases further processing since extra whitespace is just ignored, according to the rules we’ve been given.
Also notice the return value from parsing. In the rules section we provide a return value, a hash reference, in the final action code block executed.
sub parse{
my($self, $input) =
@_;
$input =~ tr/\t/ /s;
$input =~ tr/ //s;
$self->YYData->{INPUT} = $input;
my $result = $self->YYParse(yylex => \\&lexer, yyerror => \\&error);
return $result;
}
◇
Fragment referenced in 16.
This is really just about the most minimal error handling function there can be! All this does is print “syntax error”when the parser encounters a problem.
sub error{
exists $_[0]->YYData->{ERRMSG}
and do{
print $_[0]->YYData->{ERRMSG};
return;
};
print "syntax␣error\n";
}
◇
Fragment referenced in 16.
$ yapp -m Ch2 perl/ch-2.yp; mv Ch2.pm perl; perl -I. ch-2.pl {% id field1="value1" field2="value2" field3=42 %} { name => id fields => { field1 => value1 field2 => value2 field3 => 42 } } {% youtube title="Title␣\"quoted\"␣done" %} { name => youtube fields => { field1 => value1 field2 => value2 field3 => 42 title => Title } } {% youtube title="Title␣with␣escaped␣backslash␣\\" %} { name => youtube fields => { field1 => value1 field2 => value2 field3 => 42 title => Title } }
Published by Unknown on Saturday 09 March 2024 22:04
I can’t be the only programmer who does this. You’re looking for an online service to fill some need in your life. You look at three or four competing products and they all get close but none of them do everything you want. Or maybe they do tick all the boxes but they cost that little bit more than you’re comfortable paying. After spending a few hours on your search that little voice pops up in your head with that phrase that you really don’t want to hear:
Maybe you should just write your own version. How hard can it be?
A couple of hours later, you have something that vaguely works, you’ve learned more than you thought there was to learn about some obscure corner of life and you’re the proud owner of another new domain.
Please tell me it’s not just me.
So today I’ve been working on my Linktree clone.
Honestly, I can’t remember what it was about Linktree or its existing clones that I didn’t like. I suspect it’s that I just wanted more control over my links page than a hosted service would give me. All I can be sure of is that in September 2022 I made the first commit to a project that, eighteen months later, I’m still maintaining and improving.
To be fair to myself, I didn’t buy a new domain. That means I’m getting better, right? The output is hosted at links.davecross.co.uk. I’m not even paying for hosting as it’s all hosted on GitHub Pages – it’s a static site that has occasional changes, so it’s perfect for GitHub Pages.
But I have spent quite a lot of time working on the code. Probably more than is reasonable for a web site that gets a dozen visits in a good month. Work on it seems to come in waves. I’ll go for months without touching it, and then I’ll spend a week or so working on it pretty much every day. Over the last 24 hours or so, I’ve passed an important milestone. Like all of these little side projects, this one started out as a largely unstructured code dump – as I worked to get it doing something that approximated the original goal. Then I’ll spend some time (months, usually) where fixes and improvements are implemented by hacking on the original horrible code. At some point. I’ll realise that I’m making things too difficult for myself and I’ll rewrite it (largely from scratch) to be better structured and easier to maintain. That’s where I got to today. The original single-file code dump has been rewritten into something that’s far nicer to work on. And as a side benefit, I’ve rewritten it all using Perl’s new, built-in object orientation features – which I’m loving.
Oh, and I guess that’s the upside of having little side projects like this – I get to try out new features like the new OO stuff in a no-pressure environment. And just spending time doing more programming has to make you a better programmer, right? And surely it’s just a matter of time before one of these projects takes off and turns me into a millionaire! I’m not saying for a minute that having pointless side projects is a bad idea. I’m just wondering how many pointless side projects are too many
So, that’s my guilty secret – I’m a serial writer of code that doesn’t really need to be written. What about you? How many pointless side projects do you have? And how much of your spare time do they use up?
The post Pointless personal side projects appeared first on Perl Hacks.
Published by alh on Tuesday 05 March 2024 12:33
Paul writes:
``` Hours:
1 = Allow space in -M
option
https://github.com/Perl/perl5/pull/21935
3 = Tidy up / remove builtin
unimport logic
https://github.com/Perl/perl5/pull/22002
https://github.com/Perl/perl5/pull/22009
5.5 = use VERSION
restrictions
https://github.com/Perl/perl5/pull/21980
https://github.com/Perl/perl5/pull/21997
https://github.com/Perl/perl5/pull/22057
1 = class.c bugfix https://github.com/Perl/perl5/pull/21957
2 = builtin::numify https://github.com/Perl/perl5/pull/21982
1 = Tests for class.c non-ASCII UTF-8 https://github.com/Perl/perl5/pull/21983
1.5 = Logical xor operator (^^) https://github.com/Perl/perl5/pull/21996
Total: 15 hours. ```
Published by alh on Tuesday 05 March 2024 07:44
Dave writes:
(this report covers two months)
This is my monthly report on work done during Jan,Feb 2024 covered by my TPF perl core maintenance grant.
I spent the last two months mainly on two goals.
1) Understanding XS better so that I can then decide how to update the XS ecosystem to better support a reference-counted stack; as an example, automatically removing the need to call XSUBs via a wrapper in some circumstances.
Doing this led me down a rabbit hole of realising how awful our current XS documentation is. Just about every section I read resulted in confusion, followed by time out to experiment and/or to look at the ParseXS src code to try to understand what the documentation was trying to tell me. It's also very out of date: telling us of exciting "new" features introduced 25 years ago.
The net result of this is that I now have about 1000 lines of notes on "things to fix in the XS docs". I intend sometime soon to completely revamp perlxs.pod and perlxstut.pod, based on these notes. Which is a bit of sidetrack from getting XS working better under PERL_RC_STACK builds. And doing PERL_RC_STACK was itself initially a sidetrack from doing more work on perl signatures. Such is often the way when working on perl.
2) General small tasks to help get blead into shape for the 5.40 release, such as analysing and reducing smoke failures, fixing bugs, and fixing any Deparse regressions that have crept in over the last year.
SUMMARY:
* 0:38 #21822: BBC: Blead Breaks Variable::Magic
* 1:20 #21876: BBC: 5.39.7 breaks GONZUS/Cache-utLRU-0.002000.tar.gz
* 3:21 #21969: clone-with-stack.t crash
* 2:17 fix Test -deparse failures
* 1:35 fix minitest failures
* 3:39 make __LINE__
etc Deparse batter
* 1:57 make stack reference counted
* 30:30 make stack reference counted - XS
* 19:46 process p5p mailbox
* 1:28 reduce build stderr noise
* 8:33 reduce smoke failures
TOTAL: * 75:04 (HH::MM)
Published on Sunday 03 March 2024 16:52
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
You are given an array of positive integers, @ints. Write a script to find out how many integers have even number of digits.
The majory of the work can be done in a single line. Conveniently the tr function returns the number of characters effected by the command. For our purposes that means telling tr to delete all numerals. We then check if the number of numerals removed is even inside of a grep block. The number of matches is then returned. Note the one catch, in order to use tr we need to assign $_ to a temporary value, $x. Otherwise we would get an error Modification of a read-only value.
sub count_even_digits{
return 0 +
grep {
my $x = $_; $x =~ tr/[0-9]//d % 2 == 0
}
@_;
}
◇
Fragment referenced in 2.
The rest of the code just tests this function.
MAIN:{
say count_even_digits 10, 1, 111, 24, 1000;
say count_even_digits 111, 1, 11111;
say count_even_digits 2, 8, 1024, 256;
}
◇
Fragment referenced in 2.
$ perl perl/ch-1.pl 3 0 1
You are given an array of integers, @int and an integer $k. Write a script to find the sum of values whose index binary representation has exactly $k number of 1-bit set.
First, let’s concern ourselves with counting set bits. Here we can re-use some code that we’ve used before. This is a pretty standard way to count bits. This procedure is to do a bitwise AND operation for the least significant bit and check if it is set. We then right shift and repeat until no bits remain. This code is actually a modification of code used in TWC 079!
sub count_bits{
my($x) =
@_;
my $total_count_set_bit = 0;
while($x){
my $b = $x & 1;
$total_count_set_bit++ if $b;
$x = $x >> 1;
}
return $total_count_set_bit;
}
◇
Fragment referenced in 7.
With that necessary work taken care of we need to loop over the given array of integers and (1) check to see if the index contains the correct number of set bits and, if that is the case, add to the rolling sum. Finally, return the sum.
sub sum_of_values{
my $k = shift;
my(
@n) =
@_;
my $sum;
do{
$sum += $_[$_] if count_bits($_) == $k;
} for 0 ..
@n - 1;
return $sum;
}
◇
Fragment referenced in 7.
The rest of the code drives some tests.
MAIN:{
say sum_of_values 1, 2, 5, 9, 11, 3;
say sum_of_values 2, 2, 5, 9, 11, 3;
say sum_of_values 0, 2, 5, 9, 11, 3;
}
◇
Fragment referenced in 7.
$ perl perl/ch-2.pl 17 11 2
Published by perlancar on Friday 01 March 2024 00:00
dist | author | abstract | date |
---|---|---|---|
Acme-CPANModules-ArrayData | PERLANCAR | List of modules related to ArrayData | 2024-02-05T00:05:46 |
Acme-CPANModules-FormattingDate | PERLANCAR | List of various methods to format dates | 2024-02-18T14:01:27 |
Acme-CPANModules-HashData | PERLANCAR | List of modules related to HashData | 2024-02-06T00:05:32 |
Acme-CPANModules-Import-CPANRatings-User-davidgaramond | PERLANCAR | List of modules mentioned by CPANRatings user davidgaramond | 2024-02-28T00:05:24 |
Acme-CPANModules-InfoFromCPANTesters | PERLANCAR | List of distributions that gather information from CPANTesters | 2024-02-18T14:03:11 |
Acme-CPANModules-InterestingTies | PERLANCAR | List of interesting uses of the tie() interface | 2024-02-29T00:05:11 |
Acrux-DBI | ABALAMA | Database independent interface for Acrux applications | 2024-02-05T18:44:46 |
Alien-Cowl | ZMUGHAL | Find or build Cowl | 2024-02-15T03:24:53 |
Alien-Qhull | DJERIUS | Build and Install the Qhull library | 2024-02-09T17:38:52 |
AnyEvent-Sway | JOHNMERTZ | communicate with the Sway window manager | 2024-02-09T00:42:07 |
App-GnuCash-MembershipUtils | PDURDEN | A group of perl modules and scripts to help in using GnuCash for membership. | 2024-02-27T02:41:31 |
App-ISBN-Check | SKIM | Tool for ISBN checking. | 2024-02-25T18:59:34 |
App-MARC-Record-Stats | SKIM | Tool to work with MARC::Record::Stats on MARC dataset. | 2024-02-21T11:20:06 |
App-MergeCal | DAVECROSS | 2024-02-02T17:37:26 | |
App-Prove-Plugin-TestArgs | SVW | A prove plugin to configure test aliases and arguments | 2024-02-07T12:49:02 |
App-cdbookmark | PERLANCAR | Change directory to one from the list | 2024-02-03T00:05:45 |
App-grep-similar-text | PERLANCAR | Print lines similar to the specified text | 2024-02-01T00:06:12 |
App-zen | LITCHIE | Zen is a markdown based literate programming tool | 2024-02-05T05:48:06 |
Bencher-Scenarios-Log-Dispatch | PERLANCAR | Bencher scenarios related to Log::Dispatch modules | 2024-02-04T00:05:28 |
Bencher-Scenarios-Log-Dispatch-FileRotate | PERLANCAR | Scenarios to benchmark Log::Dispatch::FileRotate | 2024-02-11T00:05:41 |
Bundle-WATERKIP | WATERKIP | A mono repo for perl scripts and modules which WATERKIP likes | 2024-02-27T23:00:33 |
Chess-ELO-FIDE | NICEPERL | Download and store FIDE ratings | 2024-02-24T19:06:41 |
Common-Log-Parser | RRWO | Parse the common log format lines used by Apache | 2024-02-09T15:12:27 |
Comparer | PERLANCAR | Reusable comparer subroutines | 2024-02-08T00:11:13 |
Comparer-by_similarity | PERLANCAR | Compare similarity to a reference string | 2024-02-23T02:06:32 |
Comparer-similarity | PERLANCAR | Compare similarity to a reference string | 2024-02-24T00:06:09 |
DBIx-Class-FilterColumn-Encrypt | LEONT | Transparently encrypt columns in DBIx::Class | 2024-02-03T15:22:04 |
Dancer2-Controllers | RAWLEYFOW | A tool to allow OO style route declaration in Dancer2 | 2024-02-14T22:00:57 |
Data-Login | SKIM | Data objects for login. | 2024-02-05T22:13:16 |
Data-Sah-FilterBundle-Filename-Safe | PERLANCAR | Sah filters related to removing problematic characters from filename | 2024-02-10T00:06:19 |
Data-Structure-Deserialize-Auto | TYRRMINAL | Deserializes data structures from perl, JSON, YAML, or TOML data, from strings or files | 2024-02-22T18:13:45 |
Data-Text-Simple | SKIM | Data objects for text in language. | 2024-02-29T17:29:50 |
Data-Transfigure | TYRRMINAL | performs rule-based data transfigurations of arbitrary structures | 2024-02-19T20:39:03 |
Date-Holidays-CW | WATERKIP | Curacoa's official holidays | 2024-02-08T07:49:12 |
Devel-Confess-Source-Patch-ExcludePackage | PERLANCAR | Exclude some packages from source trace | 2024-02-25T00:05:42 |
Dist-Zilla-Plugin-GitHub-Offline | LEONT | Add a GitHub repo's info to META.{yml,json} | 2024-02-06T19:19:02 |
File-Util-Rename | PERLANCAR | Utilities related to renaming files | 2024-02-12T00:06:03 |
Games-Sudoku-Html | SHE | Visualize and play collections of standard 9×9 Sudoku in your browser. | 2024-02-24T20:23:44 |
Games-Sudoku-Pdf | SHE | Produce pdf files from your digital Sudoku sources or collections. | 2024-02-24T19:57:08 |
Locale-CLDR-Locales-Aa | JGNI | Locale::CLDR – Data Package ( Perl localization data for Afar ) | 2024-02-25T13:32:59 |
Locale-CLDR-Locales-Ab | JGNI | Locale::CLDR – Data Package ( Perl localization data for Abkhazian ) | 2024-02-25T13:34:25 |
Locale-CLDR-Locales-An | JGNI | Locale::CLDR – Data Package ( Perl localization data for Aragonese ) | 2024-02-25T13:39:26 |
Locale-CLDR-Locales-Ann | JGNI | Locale::CLDR – Data Package ( Perl localization data for Obolo ) | 2024-02-25T13:40:49 |
Locale-CLDR-Locales-Apc | JGNI | Locale::CLDR – Data Package ( ) | 2024-02-25T13:42:12 |
Locale-CLDR-Locales-Arn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Mapuche ) | 2024-02-25T13:43:47 |
Locale-CLDR-Locales-Ba | JGNI | Locale::CLDR – Data Package ( Perl localization data for Bashkir ) | 2024-02-25T13:49:23 |
Locale-CLDR-Locales-Bal | JGNI | Locale::CLDR – Data Package ( Perl localization data for Baluchi ) | 2024-02-25T13:49:34 |
Locale-CLDR-Locales-Bew | JGNI | Locale::CLDR – Data Package ( Perl localization data for Betawi ) | 2024-02-25T13:54:02 |
Locale-CLDR-Locales-Bgc | JGNI | Locale::CLDR – Data Package ( Perl localization data for Haryanvi ) | 2024-02-25T13:56:59 |
Locale-CLDR-Locales-Bgn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Western Balochi ) | 2024-02-25T13:57:19 |
Locale-CLDR-Locales-Bho | JGNI | Locale::CLDR – Data Package ( Perl localization data for Bhojpuri ) | 2024-02-25T13:58:45 |
Locale-CLDR-Locales-Blo | JGNI | Locale::CLDR – Data Package ( Perl localization data for Anii ) | 2024-02-25T14:00:25 |
Locale-CLDR-Locales-Blt | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tai Dam ) | 2024-02-25T14:00:36 |
Locale-CLDR-Locales-Bss | JGNI | Locale::CLDR – Data Package ( Perl localization data for Akoose ) | 2024-02-25T14:08:19 |
Locale-CLDR-Locales-Byn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Blin ) | 2024-02-25T14:08:31 |
Locale-CLDR-Locales-Cad | JGNI | Locale::CLDR – Data Package ( Perl localization data for Caddo ) | 2024-02-25T14:11:41 |
Locale-CLDR-Locales-Cch | JGNI | Locale::CLDR – Data Package ( Perl localization data for Atsam ) | 2024-02-25T14:11:52 |
Locale-CLDR-Locales-Cho | JGNI | Locale::CLDR – Data Package ( Perl localization data for Choctaw ) | 2024-02-25T14:16:44 |
Locale-CLDR-Locales-Cic | JGNI | Locale::CLDR – Data Package ( Perl localization data for Chickasaw ) | 2024-02-25T14:19:31 |
Locale-CLDR-Locales-Co | JGNI | Locale::CLDR – Data Package ( Perl localization data for Corsican ) | 2024-02-25T14:21:02 |
Locale-CLDR-Locales-Csw | JGNI | Locale::CLDR – Data Package ( Perl localization data for Swampy Cree ) | 2024-02-25T14:22:49 |
Locale-CLDR-Locales-Cv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Chuvash ) | 2024-02-25T14:25:39 |
Locale-CLDR-Locales-Dv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Divehi ) | 2024-02-25T14:35:09 |
Locale-CLDR-Locales-Frr | JGNI | Locale::CLDR – Data Package ( Perl localization data for Northern Frisian ) | 2024-02-25T14:51:31 |
Locale-CLDR-Locales-Gaa | JGNI | Locale::CLDR – Data Package ( Perl localization data for Ga ) | 2024-02-25T14:54:34 |
Locale-CLDR-Locales-Gez | JGNI | Locale::CLDR – Data Package ( Perl localization data for Geez ) | 2024-02-25T14:57:36 |
Locale-CLDR-Locales-Gn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Guarani ) | 2024-02-25T14:59:14 |
Locale-CLDR-Locales-Hnj | JGNI | Locale::CLDR – Data Package ( Perl localization data for Hmong Njua ) | 2024-02-25T15:09:00 |
Locale-CLDR-Locales-Ie | JGNI | Locale::CLDR – Data Package ( Perl localization data for Interlingue ) | 2024-02-25T15:20:31 |
Locale-CLDR-Locales-Io | JGNI | Locale::CLDR – Data Package ( Perl localization data for Ido ) | 2024-02-25T15:23:42 |
Locale-CLDR-Locales-Iu | JGNI | Locale::CLDR – Data Package ( Perl localization data for Inuktitut ) | 2024-02-25T15:26:52 |
Locale-CLDR-Locales-Jbo | JGNI | Locale::CLDR – Data Package ( Perl localization data for Lojban ) | 2024-02-25T15:28:43 |
Locale-CLDR-Locales-Kaj | JGNI | Locale::CLDR – Data Package ( Perl localization data for Jju ) | 2024-02-25T15:34:54 |
Locale-CLDR-Locales-Kcg | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tyap ) | 2024-02-25T15:36:25 |
Locale-CLDR-Locales-Ken | JGNI | Locale::CLDR – Data Package ( Perl localization data for Kenyang ) | 2024-02-25T15:39:38 |
Locale-CLDR-Locales-Kpe | JGNI | Locale::CLDR – Data Package ( Perl localization data for Kpelle ) | 2024-02-25T15:51:57 |
Locale-CLDR-Locales-Kxv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Kuvi ) | 2024-02-25T15:59:25 |
Locale-CLDR-Locales-La | JGNI | Locale::CLDR – Data Package ( Perl localization data for Latin ) | 2024-02-25T16:01:00 |
Locale-CLDR-Locales-Lij | JGNI | Locale::CLDR – Data Package ( Perl localization data for Ligurian ) | 2024-02-25T16:05:34 |
Locale-CLDR-Locales-Lmo | JGNI | Locale::CLDR – Data Package ( Perl localization data for Lombard ) | 2024-02-25T16:07:06 |
Locale-CLDR-Locales-Mdf | JGNI | Locale::CLDR – Data Package ( Perl localization data for Moksha ) | 2024-02-25T16:18:24 |
Locale-CLDR-Locales-Mic | JGNI | Locale::CLDR – Data Package ( Perl localization data for Mi'kmaw ) | 2024-02-25T16:25:46 |
Locale-CLDR-Locales-Moh | JGNI | Locale::CLDR – Data Package ( Perl localization data for Mohawk ) | 2024-02-25T16:30:37 |
Locale-CLDR-Locales-Mus | JGNI | Locale::CLDR – Data Package ( Perl localization data for Muscogee ) | 2024-02-25T16:35:33 |
Locale-CLDR-Locales-Myv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Erzya ) | 2024-02-25T16:38:20 |
Locale-CLDR-Locales-Nqo | JGNI | Locale::CLDR – Data Package ( Perl localization data for N’Ko ) | 2024-02-25T16:49:31 |
Locale-CLDR-Locales-Nr | JGNI | Locale::CLDR – Data Package ( Perl localization data for South Ndebele ) | 2024-02-25T16:49:40 |
Locale-CLDR-Locales-Nso | JGNI | Locale::CLDR – Data Package ( Perl localization data for Northern Sotho ) | 2024-02-25T16:51:06 |
Locale-CLDR-Locales-Nv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Navajo ) | 2024-02-25T16:52:52 |
Locale-CLDR-Locales-Ny | JGNI | Locale::CLDR – Data Package ( Perl localization data for Nyanja ) | 2024-02-25T16:54:29 |
Locale-CLDR-Locales-Oc | JGNI | Locale::CLDR – Data Package ( Perl localization data for Occitan ) | 2024-02-25T16:56:13 |
Locale-CLDR-Locales-Osa | JGNI | Locale::CLDR – Data Package ( Perl localization data for Osage ) | 2024-02-25T16:59:38 |
Locale-CLDR-Locales-Pap | JGNI | Locale::CLDR – Data Package ( Perl localization data for Papiamento ) | 2024-02-25T17:02:20 |
Locale-CLDR-Locales-Pis | JGNI | Locale::CLDR – Data Package ( Perl localization data for Pijin ) | 2024-02-25T17:04:08 |
Locale-CLDR-Locales-Quc | JGNI | Locale::CLDR – Data Package ( Perl localization data for Kʼicheʼ ) | 2024-02-25T17:10:41 |
Locale-CLDR-Locales-Raj | JGNI | Locale::CLDR – Data Package ( Perl localization data for Rajasthani ) | 2024-02-25T17:10:54 |
Locale-CLDR-Locales-Rhg | JGNI | Locale::CLDR – Data Package ( Perl localization data for Rohingya ) | 2024-02-25T17:12:17 |
Locale-CLDR-Locales-Rif | JGNI | Locale::CLDR – Data Package ( Perl localization data for Riffian ) | 2024-02-25T17:13:41 |
Locale-CLDR-Locales-Scn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Sicilian ) | 2024-02-25T17:27:35 |
Locale-CLDR-Locales-Sdh | JGNI | Locale::CLDR – Data Package ( Perl localization data for Southern Kurdish ) | 2024-02-25T17:29:16 |
Locale-CLDR-Locales-Shn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Shan ) | 2024-02-25T17:36:55 |
Locale-CLDR-Locales-Sid | JGNI | Locale::CLDR – Data Package ( Perl localization data for Sidamo ) | 2024-02-25T17:37:33 |
Locale-CLDR-Locales-Skr | JGNI | Locale::CLDR – Data Package ( ) | 2024-02-25T17:40:13 |
Locale-CLDR-Locales-Sma | JGNI | Locale::CLDR – Data Package ( Perl localization data for Southern Sami ) | 2024-02-25T17:41:45 |
Locale-CLDR-Locales-Smj | JGNI | Locale::CLDR – Data Package ( Perl localization data for Lule Sami ) | 2024-02-25T17:43:11 |
Locale-CLDR-Locales-Sms | JGNI | Locale::CLDR – Data Package ( Perl localization data for Skolt Sami ) | 2024-02-25T17:45:00 |
Locale-CLDR-Locales-Ss | JGNI | Locale::CLDR – Data Package ( Perl localization data for Swati ) | 2024-02-25T17:49:56 |
Locale-CLDR-Locales-Ssy | JGNI | Locale::CLDR – Data Package ( Perl localization data for Saho ) | 2024-02-25T17:51:22 |
Locale-CLDR-Locales-St | JGNI | Locale::CLDR – Data Package ( Perl localization data for Southern Sotho ) | 2024-02-25T17:51:52 |
Locale-CLDR-Locales-Syr | JGNI | Locale::CLDR – Data Package ( Perl localization data for Syriac ) | 2024-02-25T17:56:10 |
Locale-CLDR-Locales-Szl | JGNI | Locale::CLDR – Data Package ( Perl localization data for Silesian ) | 2024-02-25T17:57:55 |
Locale-CLDR-Locales-Tig | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tigre ) | 2024-02-25T18:04:08 |
Locale-CLDR-Locales-Tn | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tswana ) | 2024-02-25T18:07:12 |
Locale-CLDR-Locales-Tok | JGNI | Locale::CLDR – Data Package ( Perl localization data for Toki Pona ) | 2024-02-25T18:08:49 |
Locale-CLDR-Locales-Tpi | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tok Pisin ) | 2024-02-25T18:09:03 |
Locale-CLDR-Locales-Trv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Taroko ) | 2024-02-25T18:13:13 |
Locale-CLDR-Locales-Trw | JGNI | Locale::CLDR – Data Package ( Perl localization data for Torwali ) | 2024-02-25T18:13:24 |
Locale-CLDR-Locales-Ts | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tsonga ) | 2024-02-25T18:15:02 |
Locale-CLDR-Locales-Tyv | JGNI | Locale::CLDR – Data Package ( Perl localization data for Tuvinian ) | 2024-02-25T18:18:06 |
Locale-CLDR-Locales-Ve | JGNI | Locale::CLDR – Data Package ( Perl localization data for Venda ) | 2024-02-25T18:24:31 |
Locale-CLDR-Locales-Vec | JGNI | Locale::CLDR – Data Package ( Perl localization data for Venetian ) | 2024-02-25T18:25:52 |
Locale-CLDR-Locales-Vmw | JGNI | Locale::CLDR – Data Package ( Perl localization data for Makhuwa ) | 2024-02-25T18:28:42 |
Locale-CLDR-Locales-Wa | JGNI | Locale::CLDR – Data Package ( Perl localization data for Walloon ) | 2024-02-25T18:30:55 |
Locale-CLDR-Locales-Wal | JGNI | Locale::CLDR – Data Package ( Perl localization data for Wolaytta ) | 2024-02-25T18:33:42 |
Locale-CLDR-Locales-Wbp | JGNI | Locale::CLDR – Data Package ( Perl localization data for Warlpiri ) | 2024-02-25T18:33:50 |
Locale-CLDR-Locales-Xnr | JGNI | Locale::CLDR – Data Package ( Perl localization data for Kangri ) | 2024-02-25T18:37:03 |
Locale-CLDR-Locales-Za | JGNI | Locale::CLDR – Data Package ( Perl localization data for Zhuang ) | 2024-02-25T18:44:50 |
Microsoft-Teams-WebHook | TYRRMINAL | Microsoft Teams WebHook with AdaptiveCards for formatting notifications | 2024-02-20T19:13:14 |
Mo-utils-IRI | SKIM | Mo utilities for IRI. | 2024-02-29T21:11:02 |
Mo-utils-URI | SKIM | Mo utilities for URI. | 2024-02-11T16:17:45 |
Mojolicious-Plugin-INIConfig-Extended | HESCO | Mojolicious Plugin to overload a Configuration | 2024-02-13T02:33:46 |
Mojolicious-Plugin-WebComponent | RES | An effort to make creating and using custom web components easier | 2024-02-29T16:06:39 |
Net-EANSearch | JANW | Perl module for EAN and ISBN lookup and validation using the API on https://www.ean-search.org | 2024-02-13T15:30:27 |
PDL-Opt-GLPK | SOMMREY | PDL interface to the GNU Linear Programming Kit | 2024-02-21T20:32:39 |
Perlgram-Bot | AMIRCANDY | 2024-02-26T10:23:19 | |
Plack-App-ChangePassword | SKIM | Plack change password application. | 2024-02-08T21:15:14 |
Pod-Weaver-Plugin-Sah-SchemaBundle | PERLANCAR | Plugin to use when building Sah::SchemaBundle::* distribution | 2024-02-26T00:06:02 |
RDF-Cowl | ZMUGHAL | A lightweight API for working with OWL 2 ontologies | 2024-02-15T03:37:41 |
SPVM-HTTP-Tiny | KIMOTO | HTTP Client | 2024-02-23T08:53:30 |
Sah-Schemas-Comparer | PERLANCAR | Sah schemas related to Comparer | 2024-02-16T00:06:37 |
Sah-Schemas-SortKey | PERLANCAR | Sah schemas related to SortKey | 2024-02-18T14:01:38 |
Sort-BySimilarity | PERLANCAR | Sort by most similar to a reference string | 2024-02-02T00:05:29 |
SortExample | PERLANCAR | Sort examples | 2024-02-27T00:05:08 |
SortKey | PERLANCAR | Reusable sort key generators | 2024-02-14T00:05:41 |
SortKey-Num-by_length | PERLANCAR | String length as sort key | 2024-02-15T00:05:40 |
SortKey-Num-length | PERLANCAR | String length as sort key | 2024-02-15T00:05:51 |
Sorter | PERLANCAR | Sorter | 2024-02-07T00:11:23 |
Sorter-by_similarity | PERLANCAR | Sort by most similar to a reference string | 2024-02-13T00:06:16 |
Tags-HTML-ChangePassword | SKIM | Tags helper for change password. | 2024-02-07T20:04:02 |
Tie-Hash-HashData | PERLANCAR | Access HashData object as a tied hash | 2024-02-09T00:05:25 |
Tk-AppWindow | HANJE | an application framework based on Tk | 2024-02-28T15:29:57 |
WWW-Suffit-Plugin-ConfigAuth | ABALAMA | The Suffit plugin for authentication and authorization providing via configuration | 2024-02-22T08:17:35 |
WWW-Suffit-Plugin-FileAuth | ABALAMA | The Suffit plugin for authentication and authorization by password file | 2024-02-22T11:39:04 |
WWW-Suffit-Plugin-SuffitAuth | ABALAMA | The Suffit plugin for Suffit API authentication and authorization providing | 2024-02-22T08:16:09 |
mojo-util-benchmark | CRLCU | A set of utilities for working with collections of data. | 2024-02-07T13:49:03 |
Number of new CPAN distributions this period: 155
Number of authors releasing new CPAN distributions this period: 26
Authors by number of new CPAN distributions this period:
No | Author | Distributions |
---|---|---|
1 | JGNI | 88 |
2 | PERLANCAR | 27 |
3 | SKIM | 8 |
4 | ABALAMA | 4 |
5 | TYRRMINAL | 3 |
6 | SHE | 2 |
7 | LEONT | 2 |
8 | ZMUGHAL | 2 |
9 | WATERKIP | 2 |
10 | LITCHIE | 1 |
11 | AMIRCANDY | 1 |
12 | HANJE | 1 |
13 | RAWLEYFOW | 1 |
14 | JOHNMERTZ | 1 |
15 | CRLCU | 1 |
16 | DJERIUS | 1 |
17 | JANW | 1 |
18 | SVW | 1 |
19 | PDURDEN | 1 |
20 | RES | 1 |
21 | HESCO | 1 |
22 | NICEPERL | 1 |
23 | SOMMREY | 1 |
24 | KIMOTO | 1 |
25 | RRWO | 1 |
26 | DAVECROSS | 1 |