How deep is a recursion in Perl?

Perl Maven

Published by Gabor Szabo on Saturday 31 July 2021 10:30

We have discussed recursion in Perl and the problem with recursion that is too deep, but how can you find out the current depth of the recursion?

perlbrew improved

dev.to #perl

Published by David Cantrell on Friday 30 July 2021 23:03

I like to keep all my builds of perl under the control of perlbrew, so I can easily switch between them. I occasionally need to build a version of perl that hasn't been released yet, and maybe hasn't even been merged into blead (which is what the perl5 project calls the master branch). That's fine, perlbrew can just build from a git checkout. However, you need to give it some extra arguments to avoid confusion (you generally don't want it to build something called 'perl-5.35.3' when that's just the latest version to have been released in the repo, but not what you're actually building) and to help you remember which build is which. So, as is traditional for a Unixy gentleman with a problem to solve, I wrote a small shell script.

Source this into your shell after loading perlbrew and if you then say perlbrew git-install from the root of a git repository it will build a perl called git-$reponame-$branchname-$commit.

Are you using Cache::Memcached and its ->stats method?

blogs.perl.org

Published by Lee J on Thursday 29 July 2021 14:40

It's very slow if you have more than a few thousand keys in memcached. Not an unusual use case I think? I've got a fix here, which appears to DTRT: https://rt.cpan.org/Ticket/Display.html?id=138133. Maybe? I didn't spend too long looking at memcached's low level wire protocol.

The patch passes all the module's current tests and works for us. It took our CPU load from being pegged at 75% all of the time to being idle. So, if you're using Cache::Memcached, and the ->stats method (which isn't in the XS version of the module) then you might want this patch.

On that note - who is maintaining Cache::Memcached? The last release was in 2012. This isn't a high river module, but any app of significant size or age is *probably* using it and if they're using the ->stats method then ... Sure there's the ::Fast version, but I suspect this version is in a lot of places.

So if you know someone who knows someone who can prod the current maintainers then please point them at this post/patch. If you're using Cache::Memcached then perhaps try out this patch as well.

Release 1.56 of perl-workflow, a bug fix release

dev.to #perl

Published by jonasbn on Thursday 29 July 2021 17:50

With release 1.55 we unfortunately introduced a minor bug as observed by the OpenXPKI project.

A workaround was implemented and due to fast feedback we where able to get the issue pin-pointed for correction. The only issue delaying this important bug fix release was summer holidays, but we have just shipped and we are now focusing our attention to our upcoming 2.0 release.

This change in focus will mean that we will only be making bug fix releases to the 1.X branch. Since we are doing trunk based development, the master branch is currently considered unstable, installations and use should be based on official releases.

We still have some way to go before the first pre-release of 2.0 will be uploaded to CPAN, but I am confident that it will be completed within the next weeks, since holiday season is good to open source.

Here follows the change log of release 1.56.

Change Log

The original is available on GitHub

1.56 2021-07-28 Bug fix release, update recommended

  • PR #139 addresses an issue introduced in 1.55, where action configurations would contain unnecessary information

  • Elimination of global state, with improved abstraction the complexity could be removed via PR #140

  • PR #141 improves test suite, following up on PR #131

  • PR #132 follows up on issue #129 by improving documentation on group property of Workflow::Action

  • Elimination of warning about undefined value, which surfaced with release 1.55, adressed with PR #135

  • PR #131 documents the importance of overriding init for processing of parameters and not using new

  • PR #130 addresses issue #129, respects encapsulation by adhering to the API

  • Improves some error and log messages via PR #128

Zapp: Runbook Automation

dev.to #perl

Published by Doug Bell on Thursday 29 July 2021 00:08

GitHub logo preaction / Zapp

Create plans for your Minions to run

I hate runbooks. I've been an SRE from since we were called webmasters. In all this time, the least helpful part of my job has been the lists of commands to run when there's a problem. Often out-of-date, frequently lacking in context, and altogether useless when production is burning around you and clients are banging on the door. I'm a programmer. I don't perform tedious tasks, I automate them. Why, then, should I like documenting tedious tasks?

I hate Jenkins. No, that's not quite true. I'm disappointed in Jenkins. Parameterized builds could be such a useful tool, but the input form they provide the end-user is ugly at best, incomprehensible at worst. Jenkins's pipeline syntax opens the door to some truly amazing abilities, but there's no way for me to package those abilities in a way I can simply give to someone without training them on how to navigate Jenkins's UI.

To solve these problems, I wrote Zapp. In Zapp, I can create a plan as a series of tasks, like a Jenkins build. Plans can have input fields, like a Jenkins parameterized build. Users can then run the plan and see the output.

Zapp tasks can be more than a shell command or script. Zapp tasks have their own configuration, so I can provide a friendly form for the user to control what the task will do. Additionally, tasks output typed data that can be used as input to subsequent tasks. When the task executes, it can render its own output to show the end-user what is happening.

So, I can create a plan that asks a user to input their credentials.
Zapp form showing two inputs

Then, the plan can fetch an authentication token using those credentials.
Zapp form for GetOAuth2Token task

Finally, with this authentication token, I can perform my request.
Zapp form for Request task

Then when I want to run the plan, I can input my credentials and hit a button.
Zapp form to run the plan

As the job runs, it updates the job page. If any errors occur, the job stops and the failing task shows an error message. I can choose to re-play the job, or I can go back and fix whatever problem there is.

Zapp isn't limited to automating runbooks. Zapp provides webhook triggers to perform plans automatically. Build your software after a commit is pushed to Github, respond to Slack commands, or (when a future version adds scheduled tasks) run a nightly SQL report. Not only are these tasks automated, but they are easy to configure so that users can support themselves.

Finally, if Zapp can't do what you want, you can write your own task classes to perform tasks, type classes to accept input from users, and trigger classes to run plans automatically in response to events. Zapp is written in modern Perl using the Mojolicious web framework and the Minion task runner.

With Zapp, I can make tedious support processes into a single web form, or even a single click. As needs change, processes can be tweaked using a friendly UI. And new types of tasks can be created to provide ever more options for your users.

Zapp is very much Alpha-grade software right now: I use it personally, but there are bugs and missing features yet. The plugin APIs are pretty solid, though, so you can write your own tasks, types, and triggers. There are a lot of features that Minion provides that Zapp does not yet take advantage of, so there's plenty of possibilities for future development. If you have any questions, suggestions, issues, or want to know if Zapp can work for you, feel free to let me know at doug@preaction.me or on irc.libera.chat in #mojo-yancy.

The Funhouse Mirror of Perl Criticism

dev.to #perl

Published by Mark Gardner on Tuesday 27 July 2021 14:00

Last week’s article got a great response on Hacker News, and this particular comment caught my eye:

I think this is the real point about Perl code readability: it gives you enough flexibility to do things however you like, and as a result many programmers are faced with a mirror that reflects their own bad practices back at them.

orev, Hacker News

This is why Damian Conway’s Perl Best Practices (2005) is one of my favorite books and perlcritic, the code analyzer is one of my favorite tools. (Though the former could do with an update and the latter includes policies that contradict Conway.) Point perlcritic at your code, maybe add some other policies that agree with your house style, and gradually ratchet up the severity level from “gentle” to “brutal.” All kinds of bad juju will come to light , from wastefully using grep to having too many subroutine arguments to catching private variable use from other packages. perlcritic offers a useful baseline of conduct and you can always customize its configuration to your own tastes.

The other conformance tool in a Perl developer’s belt is perltidy, and it too has a Conway-compatible configuration as well as its default Perl Style Guide settings. I’ve found that more than anything else, perltidy helps settle arguments both between developers and between their code in helping to avoid excessive merge conflicts.

But apart from extra tools, Perl the language itself can be bent and even broken to suit just about anyone’s agenda. Those used to more bondage-and-discipline languages (hi, Java!) might feel revulsion at the lengths to which this has sometimes been taken, but per the quote above this is less an indictment of the language and more of its less methodical programmers.

Some of this behavior can be rehabilitated with perlcritic and perltidy, but what about other sins attributed to Perl? Here are a few perennial “favorites”:

Objects and Object-Oriented Programming

Perl has a minimalist object system based on earlier-available language concepts like data structures (often hashes, which it has in common with JavaScript), packages, and subroutines. Since Perl 5’s release in 1994 much verbose OO code has been written using these tools.

The good news is that since 2007 we’ve had a sophisticated metaobject-protocol-based layer on top of them called Moose, since 2010 a lightweight but forward-compatible system called Moo, and a couple of even tinier options as described in the Perl OO Tutorial. Waiting in the wings is Corinna, an effort to bring next-generation object capabilities into the Perl core itself, and Object::Pad, a testbed for some of the ideas in Corinna that you can use today in current code. (Really, please try it—the author needs feedback!)

All this is to say that 99% of the time you never need trouble yourself with bless, constructors, or writing accessors for class or object attributes. Smarter people than me have done the work for you, and you might even find a concept or three that you wish other languages had.

Contexts

There are two major ones: list and scalar. Another way to think of it is “plural” vs. “singular” in English, which is hopefully a thing you’re familiar with as you’re reading this blog.

Some functions in Perl act differently depending on whether the expected return value is a list or a scalar, and a function will provide a list or scalar context to its arguments. Mostly these act just as you would expect or would like them to, and you can find out how a function behaves by reading its documentation. Your own functions can behave like this too, but there’s usually no need as “both scalars and lists are automatically interpreted into lists.” Again, Perl’s DWIMmery at work.

Subroutine and Method Arguments

I’ve already written about this. Twice. And presented about it. Twice. The short version: Perl has signatures, but they’ve been considered experimental for a while. In the meantime, there are alternatives on CPAN. You can even have type constraints if you want.

I’ll leave you with this: Over the past month, Neil Bowers of the Perl Steering Council has been collecting quirks like these from Perl developers. The PSC is reviewing this collection for potential documentation fixes, bug fixes, further discussion, etc. I wouldn’t expect to see any fundamental changes to the language out of this effort, but it’s a good sign that potentially confusing features are being addressed.

Weekly Challenge 123

dev.to #perl

Published by Simon Green on Tuesday 27 July 2021 12:23

Two nice and quick challenge this week. Tasks, My solutions

TASK #1 › Ugly Numbers

Task

You are given an integer $n >= 1.

Write a script to find the $nth element of Ugly Numbers.

Ugly numbers are those number whose prime factors are 2, 3 or 5. For example, the first 10 Ugly Numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12.

My solution

This was relatively straight forward, although I'm not sure if my method is the most efficient (took 16 seconds to find the 1,000th ugly number).

I determine if a number is ugly by dividing it by 2, 3, 5 as many times as it leaves no remainder. If the resulting number is 1, then it is ugly.

Then it was just a case of wrapping this in a while loop decreasing $n every time a number is ugly.

Examples

$ ./ch-1.pl 7
8

$ ./ch-1.pl 10
12

TASK #2 › Square Points

Task

You are given coordinates of four points i.e. (x1, y1), (x2, y2), (x3, y3) and (x4, y4).

Write a script to find out if the given four points form a square.

My solution

Some fundamental maths is involved with this task, namely:

  • The distance between two points can found by calculating the square root of the sum of the squared difference in each of the x and y values.
  • For an item to be square, each side must be of equal length.
  • For an item to be square, the distance between points 1 and 3 must be the same as the distance between 2 and 4.

For this task I have a subroutine _distance_between that calculates the distance between two points given (x1, y1, x2 and y2). I also have a subroutine _is_square that will return 0 when one of the above conditions is false, or 1 if it appears to be a square.

One thing to note that the points provided must be sequential. You can't go from top left to bottom right. Since the task specifically mentions the order of the points, this shouldn't be an issue.

Examples

$ ./ch-2.pl 10 20 20 20 20 10 10 10
1

$ ./ch-2.pl 12 24 16 10 20 12 18 16
0

#522 - Promote Perl

Perl Weekly

Published on Monday 26 July 2021 10:00

Hi there

I am sure many of you are aware of Outreachy. It all started with GNOME's Women's Summer Outreach Program (WSOP) in 2006. The idea was to encourage women's participation in Open Source projects. In 2009, the GNOME community revived the program to encourage more women to contribute to GNOME and renamed it to GNOME Outreach Program for Women. It became a very popular program in no time and successfully brought in more women into the fold. The program was further expanded with more organisations joining in e.g. Fedora, Mozilla, JBoss, OpenStack, Subversion etc. With the additions, in 2013, the program was renamed to the Free and Open Source Software Outreach Program. At one point, there were 16 organizations involved in this program. In 2015, the program was again renamed to Outreachy.

Did I mention Perl in the above discussion?

Well, in 2014, TPF sponsored an internship for Pattawan Kaewduangdee to work on MetaCPAN under the mentorship of Olaf Alders as a part of the Outreach Program for Women. There is another name that caught my eye, Upasana Shukla. I came across a blog post by Upasana where she mentioned how GNOME's Outreach Program for Women helped her get into the Perl fold. If you look at the list of interns from the Indian subcontinent (India, Pakistan, Bangladesh, Nepal, Sri Lanka) it is amazing. In recent years, TPF has sponsored Open Food Facts projects for Outreachy. In 2020, Areesha Tariq, from Pakistan successfully got the internship to work on the Open Food Facts project. Please check out this blog post by Areesha sharing her experience. It didn't stop there, a few weeks ago, TPF announced another intern, Rosheen Naeem, again from Pakistan, to work on the Open Food Facts project. You should check out her recent blog post about her journey. It is very inspiring.

I would like to thank TPF for supporting the Perl projects and Outreachy.

I can tell you from my own experience, we have great talent in the Indian Subcontinent. I wish more and more organisations would come forward and sponsor interns from these regions. When I started The Weekly Challenge - Perl & Raku, (a.k.a Perl Weekly Challenge), I was hoping to tap into the talent pool from this region, specially young college students. As the tagline says "You do not have to be an expert" to take part in the weekly challenge. Although we do have handful of students from Russia in the team. I am glad that, at least, we have built a platform where geeks from around the world come and share their experiences every week. Maybe one day we will have sponsors to help us reach out to young talent and bring new energy into the Perl community. Sometimes I wonder why we have never had a Perl Conference on the Indian subcontinent just like we have here in Europe and America. It shouldn't be too hard to hold one as these days everything is online. We could invite guest speakers from across the globe to address the talent in the region. Is there anyone out there willing to help us orgranise Perl Conference?

A humble request to all fellow citizens of the United Kingdom, please don't listen to Boris Johnson (Prime Minister of the UK) and keep wearing masks in public and maintain social distancing.

Enjoy rest of the newsletter until then.

Perl Weekly Challenge 122: Average of Stream and Basketball Points

blogs.perl.org

Published by laurent_r on Wednesday 21 July 2021 02:19

These are some answers to the Week 122 of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few days, on July 25, 2021 at 24:00. This blog post offers some solutions to this challenge, please don’t read on if you intend to complete the challenge on your own.

Task 1: Average of Stream

You are given a stream of numbers, @N.

Write a script to print the average of the stream at every point.

Example:

Input: @N = (10, 20, 30, 40, 50, 60, 70, 80, 90, ...)
Output:      10, 15, 20, 25, 30, 35, 40, 45, 50, ...

Average of first number is 10.
Average of first 2 numbers (10+20)/2 = 15
Average of first 3 numbers (10+20+30)/3 = 20
Average of first 4 numbers (10+20+30+40)/4 = 25 and so on.

This is often called a moving average or a running average, or, more precisely in this case, a cumulative moving average, since we want to compute the mean of all data received so far.

It is of course possible to keep track of all data seen so far and, each time, to recompute the average from the whole dataset using standard formulas. However, if we have the current average and the number of values from which it was computed, it is quite easy to compute the new average with a new value. Suppose that the average of the first five values of a series is 8. This means that the sum s of the first five values was s = 5 x 8 = 40. As a new value, say 2, is taken into account, then the new sum is 42, and the new average is 42 / 6 = 7. So the rule it to multiply the current average by the current number of values, to add the new value and to divide this new sum by the new number of values, i.e. the current number of values plus 1.

Average of Stream in Raku

Implementing the rule described above is fairly straight forward. For our test, we use an infinite (lazy) arithmetic sequence with a common difference of 10 between two consecutive terms.

use v6;

my @n = 10, 20 ... Inf;
my @cum_moving_avg = @n[0];
for 1..^10 -> $i {
    @cum_moving_avg[$i] = (@cum_moving_avg[$i-1] * $i + @n[$i]) / ($i + 1);
}
say ~@cum_moving_avg;

This program displays the following output:

raku ./mvg_avg.raku
10 15 20 25 30 35 40 45 50 55

Note that, with an arithmetic sequence as input, the output sequence of moving average values is also an arithmetic sequence.

Average of Stream in Perl

This is an implementation of the same rule in Perl. We cannot use an infinite sequence in Perl, so we simply use an arithmetic sequence of 10 terms.

use strict;
use warnings;
use feature "say";

my @n = (10, 20, 30, 40, 50, 60, 70, 80, 90, 100);
my @mvg_avg = ($n[0]);
for my $i (1..9) {
    $mvg_avg[$i] = ($mvg_avg[$i-1] * $i + $n[$i]) / ($i + 1);
}
say "@mvg_avg";

This program displays the following output:

$ perl ./mvg_mean.pl
10 15 20 25 30 35 40 45 50 55

Average of Stream in Scala

This is a port to Scala of the Raku and PPerl implementations above:

object root extends App {
  val n = Array.range(10, 101, 10) // (10, 20, ... 100)
  val mvg_avg = new Array[Int](10)
  mvg_avg(0) = n(0)
  for (i <- 1 to 9) {
    mvg_avg(i) = (mvg_avg(i - 1) * i + n(i)) / (i + 1)
  }
  println(mvg_avg.mkString(" "))
}

This program yields the following result:

10 15 20 25 30 35 40 45 50 55

Average of Stream in Python

A port to Python of the Raku and Perl versions above:

n = list(range(10, 100, 10)) # [10, 20 ... 90]
mvg = [n[0]]
for i in range(1, 9):
    mvg.append((mvg[i-1] * i + n[i])  / (i + 1))
print(mvg)

Output:

$ python3 mvg_mean.py
[10, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0]

Average of Stream in C

Implementation of essentially the same algorithm in the C programming language. There is a slight change in the management of indices because the arguments passed to a C program start with argv[1} (since argv[0] contains the program name). Another slight change is that this program doesn’t populate an array of mean values, but prints out the average value as soon as it is found. This should lead to a smaller memory footprint (which may be useful if the stream is very large).

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int avg = atoi(argv[1]);
    printf("%5i  ", avg);
    for (int i = 1; i < argc - 1; i++) {
        avg = (avg * i + atoi(argv[i+1])) / (i + 1);
        printf("%3i ", avg);
    };
    printf("\n");
}

Output:

$ ./a.out 10 20 30 40 50 60 70 80 90 100
10   15  20  25  30  35  40  45  50  55

Average of Stream in Awk

Again some tweaks on the management of indices because of the specific properties and behavior of arrays in awk, but essentially the same algorithm.

{ 
    avg[0] = $1;
    print $1;
    for (i = 1; i < NF; i++) { 
         avg[i] = (avg[i-1] * i + $(i+1)) / (i+1)
         print avg[i]
    }
}

Output:

$ echo '10 20 30 40 50 60 70 80 90 100
    ' | awk -f mvg_mean.awk
10
15
20
25
30
35
40
45
50
55

Average of Stream in D

The D programming language is similar to C or C°°, except that it is supposed to be more secure.

import std.stdio;
import std.math;
import std.conv;

void main(string[] args) {
    int avg = std.conv.to!int(args[1]);
    printf ("%d ", avg);
    for (int i = 1; i < args.length - 1; i++) {
        avg = (avg * i + std.conv.to!int(args[i+1])) / (i + 1);
        printf("%3d ", avg);
    }
    printf("\n");
}

Output:

$ mvg-mean.amx 10 20 30 40 50 60 70 80 90 100
10  15  20  25  30  35  40  45  5

Task 2: Basketball Points

You are given a score $S.

You can win basketball points e.g. 1 point, 2 points and 3 points.

Write a script to find out the different ways you can score $S.

Example:

Input: $S = 4
Output: 1 1 1 1
        1 1 2
        1 2 1
        1 3
        2 1 1
        2 2
        3 1

Input: $S = 5
Output: 1 1 1 1 1
        1 1 1 2
        1 1 2 1
        1 1 3
        1 2 1 1
        1 2 2
        1 3 1
        2 1 1 1
        2 1 2
        2 2 1
        2 3
        3 1 1
        3 2

Basketball Points in Raku

I initially tried to use the | and X operators and the combinations, unique and some other method invocations to try to generate the values with a single expression, but turned out to be more difficult than I expected. So, I gave up and decided to use a good old recursive subroutine (find-dist) to generate all possible solutions leading to the target value:

use v6;

my $target = @*ARGS[0] // 5;
my @vals = 1, 2, 3;

sub find-dist ($sum, @seq) {
    for @vals -> $i {
        my $new-sum = $sum + $i;
        # if $new-sum > $target, then we don't 
        # need to test other values of @vals and
        # can use return directly instead of next 
        # since these values are in ascending order
        return if $new-sum > $target;
        my @new-seq = |@seq, $i;
        if $new-sum == $target {
            say ~@new-seq;
            return;
        } else {
            find-dist($new-sum, @new-seq);
        }
    }
}
find-dist 0, ();

This displays the following output:

$ raku ./score-dist.raku
1 1 1 1 1
1 1 1 2
1 1 2 1
1 1 3
1 2 1 1
1 2 2
1 3 1
2 1 1 1
2 1 2
2 2 1
2 3
3 1 1
3 2

$ raku ./score-dist.raku 4
1 1 1 1
1 1 2
1 2 1
1 3
2 1 1
2 2
3 1

Basketball Points in Perl

This a port to Perl of the Raku solution using a recursive subroutine:

use strict;
use warnings;
use feature "say";

my $target = shift // 5;
my @vals = (1, 2, 3);

sub find_dist  {
    my ($sum, @seq) = @_;
    for my $i (@vals) {
        my $new_sum = $sum + $i;
        # if $new_sum > $target, then we don't 
        # need to test other values of @vals and
        # can use return instead of next 
        # since these values are in ascending order
        return if $new_sum > $target;
        my @new_seq = (@seq, $i);
        if ($new_sum == $target) {
            say ""@new_seq";
            return;
        } else {
            find_dist($new_sum, @new_seq);
        }
    }
}
find_dist 0, ();

This program generates the following output:

$ perl score-dist.pl
1 1 1 1 1
1 1 1 2
1 1 2 1
1 1 3
1 2 1 1
1 2 2
1 3 1
2 1 1 1
2 1 2
2 2 1
2 3
3 1 1
3 2

$ perl score-dist.pl 4
1 1 1 1
1 1 2
1 2 1
1 3
2 1 1
2 2
3 1

Wrapping up

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 August 1, 2021. And, please, also spread the word about the Perl Weekly Challenge if you can.

Average of Stream / Basketball Points

RabbitFarm Perl

Published on Sunday 25 July 2021 18:53

The examples used here are from The Weekly Challenge problem statement and demonstrate the working solution.

Part 1

You are given a stream of numbers, @N. Write a script to print the average of the stream at every point.

Solution


use strict;
use warnings;
sub moving_average{
    my $n = 0;
    my $sum = 0;
    {
        $n += 1;
        $sum += shift;
        print $sum / $n;
        print ", " if @_;
        redo if @_;
    }
    print "\n";
}


MAIN:{
    my @N;
    for(my $i = 10; $i < 1_000_000; $i += 10){
        push @N, $i;
    }
    moving_average(@N);
}

Sample Run


$ perl perl/ch-1.pl
10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 

Notes

Typically when one thinks of a stream the idea is of a virtually endless source of data. Or, at least, data which is handled as if this were the case. Here the "stream" is simulated by a long (one million items) array.

The computation of the average as the simulated stream is evaluated is done using a redo loop. I would think it is fair to say that typically my code is somewhat verbose. I prefer to be fairly explicit in that way to enhance readability. Here, however, I try to be more terse. The "stream" is evaluated by shifting values off the array passed to the function. The array argument is also used to determine if the block should be repeated, and also to format the output.

Part 2

You are given a score $S. You can win basketball points e.g. 1 point, 2 points and 3 points. Write a script to find out the different ways you can score $S.

Solution


use strict;
use warnings;
sub basketball_points{
    my($total) = @_;
    my %points;
    my @valid_points;
    $points{"1"} = "1";
    $points{"2"} = "2";
    $points{"3"} = "3";
    while((keys %points) > 0){
        my %updated_points = ();
        for my $points (keys %points){
            my @points = split(/,/, $points);
            for my $point (1 .. 3){
                my $point_sum = unpack("%32I*", pack("I*",  (@points, $point)));
                push @valid_points, [@points, $point] if $point_sum == $total;
                $updated_points{join(",", (@points, $point))} = $point_sum if $point_sum < $total;
            }
        }
        %points = %updated_points;
    }
    return @valid_points;
}

MAIN:{
    my $S;
    $S = 4;
    print "\$S = $S\n";
    my @point_combinations = basketball_points($S);
    for my $points (basketball_points($S)){
        print join(" ", @{$points}) . "\n";
    }
    $S = 5;
    print "\n\$S = $S\n";
    @point_combinations = basketball_points($S);
    for my $points (basketball_points($S)){
        print join(" ", @{$points}) . "\n";
    }
}

Sample Run


$ perl perl/ch-2.pl
$S = 4
1 3
2 2
3 1
1 2 1
1 1 2
2 1 1
1 1 1 1

$S = 5
3 2
2 3
3 1 1
2 1 2
1 3 1
2 2 1
1 2 2
1 1 3
1 2 1 1
1 1 1 2
1 1 2 1
2 1 1 1
1 1 1 1 1

Notes

The approach here borrows heavily from the solution to the triangle problem from Challenge 117. This is a dynamic programming style solution which builds and updates lists of potential point sequences. Uniqueness is guaranteed by saving the lists as hash keys, in a command separated values string format.

References

Challenge 122

Dynamic Programming

Random Thought: Exposure of Perl in the Academic Circles

blogs.perl.org

Published by C.-Y. Fung on Thursday 22 July 2021 14:10

Today I have wandered on the famous academic paper archive and suddenly a thought popped into my mind - use Perl as the keyword in searching.

Computer science papers with "Perl" in the title
https://arxiv.org/search/advanced?advanced=1&terms-0-operator=AND&terms-0-term=Perl&terms-0-field=title&classification-computer_science=y (8*)

Computer science papers with "Lisp" in the title
https://arxiv.org/search/advanced?advanced=1&terms-0-operator=AND&terms-0-term=Lisp&terms-0-field=title&classification-computer_science=y (12**)

Computer science papers with "Ruby" in the title
https://arxiv.org/search/advanced?advanced=1&terms-0-operator=AND&terms-0-term=Ruby&terms-0-field=title&classification-computer_science=y (6***)

Computer science papers with "Julia" in the title
https://arxiv.org/search/advanced?advanced=&terms-0-term=Julia&terms-0-field=title&classification-computer_science=y (53 ****)

For Haskell: ~50

For Java: ~249

For Python: ~357

For Perl Data Language (PDL): 0


Besides writing quality software, organizing conference or blogging, Perl programmers with strong academic background might think of taking a new way to share their favorite functionalities in Perl to the world.

Link: arXiv.org submission guidelines
----
* 2 results are not relevant to the Perl programming language.
** 1 result is not relevant to the LISP programming language.
*** Similarly, 2 search results are irrelevant.
**** Similarly, 6 search results are irrelevant.

------
P. S.:
Many members in Perl community seem to share a concern of Perl being marginalized. As a newbie programmer and a selfish person, I also want Perl, a programming language I am "investing" in, can gain certain popularity and thus I can use Perl(Perl7?) in local job hunt in the future, hahaha. Therefore I keep an eye for the Perl's popularity discussion.

(cccli) 9 great CPAN modules released last week

Niceperl

Published by Unknown on Saturday 24 July 2021 20:46

Updates for great CPAN modules released last week. A module is considered great if its favorites count is greater or equal than 12.

  1. App::cpm - a fast CPAN module installer
    • Version: 0.997006 on 2021-07-22
    • Votes: 54
    • Previous version: 0.997004 was 1 month, 9 days before
  2. App::Netdisco - An open source web-based network management tool.
    • Version: 2.047008 on 2021-07-21
    • Votes: 13
    • Previous version: 2.047007 was 7 days before
  3. CryptX - Cryptographic toolkit
    • Version: 0.073 on 2021-07-18
    • Votes: 42
    • Previous version: 0.072 was 2 months, 19 days before
  4. DBD::SQLite - Self Contained SQLite RDBMS in a DBI Driver
    • Version: 1.68 on 2021-07-22
    • Votes: 96
    • Previous version: 1.66 was 10 months, 23 days before
  5. Encode - character encodings in Perl
    • Version: 3.11 on 2021-07-23
    • Votes: 54
    • Previous version: 3.10 was 2 months, 5 days before
  6. HTTP::BrowserDetect - Determine Web browser, version, and platform from an HTTP user agent string
    • Version: 3.33 on 2021-07-21
    • Votes: 22
    • Previous version: 3.31 was 11 months, 23 days before
  7. Module::CoreList - what modules shipped with versions of perl
    • Version: 5.20210723 on 2021-07-23
    • Votes: 35
    • Previous version: 5.20210620 was 1 month, 3 days before
  8. Object::Pad - a simple syntax for lexical slot-based objects
    • Version: 0.46 on 2021-07-21
    • Votes: 15
    • Previous version: 0.45 was 4 days before
  9. Test::BDD::Cucumber - Feature-complete Cucumber-style testing in Perl
    • Version: 0.81 on 2021-07-18
    • Votes: 15
    • Previous version: 0.79 was 3 months, 30 days before

(cdlxxvii) metacpan weekly report

Niceperl

Published by Unknown on Saturday 24 July 2021 20:42

This is the weekly favourites list of CPAN distributions. Votes count: 39

This week there isn't any remarkable distribution

Build date: 2021/07/24 18:42:05 GMT


Clicked for first time:


Increasing its reputation:

Deep recursion on subroutine

Perl Maven

Published by Gabor Szabo on Friday 23 July 2021 06:30

When calling a function in recursion we have to be careful to check the stop condition before we call the recursion. If not, we can end up with an infinite recursion that will end only when we have exhausted the resources of our computer.

In order to protect the user from never ending recursions, perl has a hard limit on the number of recursion and if you reach that limit you'll get a warning: Deep recursion on subroutine. The rather arbitrary limit is 100.

Let's see an example.

On the eve of CPAN Testers

blogs.perl.org

Published by Aristotle on Thursday 15 July 2021 15:34

Have a look at the CPAN Testers reports for two TRIAL releases of the same module, one from 2 days ago, the other a little over 3 years ago:

Last time, reports started coming in within hours of the release; over 60% of the picture was there within a day; some 85% after 2 days; and the first wave of reports lasted a week.

This time, it took almost a day to even start getting reports, and the diversity has been much lower. 3 days in, reports are still absent for many platforms:

  • None for NetBSD, almost none for OpenBSD.
  • Only a handful for Solaris (but I’ll admit to small surprise about that one).
  • Windows is sparse – although coverage is not notably down relative to last time.
  • Cygwin is entirely absent this time – but not a big difference from the one lone report it had last time.
  • FreeBSD and Linux are at least healthy – but no longer anywhere near comprehensively covered. (How’s that for something I’d never have expected to see?)
  • Who’da thunk the best-covered platform would someday be… Darwin?

(Also of note is that the only 5.8 tested at all so far is 5.8.9, a maintenance release from long after 5.10.0 with little real-world relevance. Last time 5.8 had good coverage, including the most important releases (5.8.1; 5.8.5; 5.8.8). (Of course, any 5.8 is better than no 5.8 at all.))

Within just a few years, we are severely down on CPAN Testers resources.

And that’s compared to 2018, which already was a long way from any kind of golden age for CPAN Testers.

CPAN Testers is on its way out.

I never bothered with CI for CPAN modules before but now it seems an unavoidable necessity.

(And common CI products have never made broad platform coverage easy…)

Released Giblog 2.0. GIblog is a tool to create your web site easily.

Giblog 2.0 Release Announcement

Giblog 2.0 is released at 2021-7-24. serve command and publish command is added.

Giblog 2.0 Release Announcement

Giblog Document

Giblog Document in CPAN.

Giblog Document

Giblog Movie

I explain how to create your website using Giblog and Perl by live coding. Giblog is a Perl module to create web sites. If you see this movie, you can create your web site using Giblog and Perl(although you need some Linux knowledge).


#521 - Floods in Perl

Perl Weekly

Published on Monday 19 July 2021 10:00

Hi there,

This week we saw the tremendous and devastating power of nature in Europe as well. The Guardian even mentioned the Moselle River at Perl in Germany. The place where Liz and Wendy attempted to re-unite the Perl 5 and Perl 6 communities as well. That was not very successful.

I was wondering what can we do?

I know a few members of the Perl community who are also volunteer firefighters. Some of them might have taken part in the rescue efforts maybe even risking their own lives. That a very generous way of helping others and helping the world when disaster strikes.

I know a few other members of the Perl community who make an effort to reduce their own carbon footprint by traveling by bike and train only. That can help postpone the disasters and if enough people do them might even prevent the disasters.

What do you do? What examples could we follow to help when disaster strikes? What could ew do to try to avoid the disasters in the first place? Write about it in a blog post and send the link to me!

Enjoy your week!

Regexp::Grammars parse text with markup or markdown

Perl Maven

Published by Gabor Szabo on Monday 19 July 2021 06:15

Parsing text with markup (or markdown) is not easy. It took me several days to wrap my head around this, but eventually I think I've figured it out.

The examples used here are from The Weekly Challenge problem statement and demonstrate the working solution.

Part 1

You are given integers 0 <= $m <= 255 and 1 <= $n <= 8. Write a script to invert $n bit from the end of the binary representation of $m and print the decimal representation of the new binary number.

Solution


use strict;
use warnings;
sub flip_bit_n{
    my($x, $n) = @_;
    my $bits = substr(unpack("B32", pack("N", $x)), 24, 8);
    my @bits = split(//, $bits);
    $bits[@bits - $n] ^= 1;
    my $flipped_decimal = unpack("N", pack("B32", substr("0" x 32 . join("", @bits), -32)));
    return $flipped_decimal;
}

MAIN:{
    my($M, $N);
    $M = 12;
    $N = 3;
    print flip_bit_n($M, $N) . "\n";
    $M = 18;
    $N = 4;
    print flip_bit_n($M, $N) . "\n";
}

Sample Run


$ perl perl/ch-1.pl
8 
26

Notes

This code re-uses much of the code from last week's challenge solution. The only difference is that this week we flip the specified nth bit using the XOR operator. I think that this may be the first time I have ever used a ^= operation!

Part 2

You are given a NxN matrix containing the distances between N cities. Write a script to find a round trip of minimum length visiting all N cities exactly once and returning to the start.

Solution


use strict;
use warnings;
use boolean;
use AI::Genetic;

use constant N => 7;

my @matrix= ([0, 5, 2, 7],
             [5, 0, 5, 3],
             [3, 1, 0, 6],
             [4, 5, 4, 0]);

sub fitness{
    my($genes) = @_;
    my $cost = 0;
    return -1 if $genes->[0] != $genes->[@{$genes} - 1];
    my @path = sort {$a <=> $b} @{$genes}[0 .. @{$genes} - 2];
    for my $i (0 .. (@path - 2)){
        return -1 if $path[$i] == $path[$i + 1];
    }
    for my $i (0 .. @{$genes} - 2){
        $cost += $matrix[$genes->[$i]][$genes->[$i + 1]];
    }
    return 1/$cost;
}

sub terminate{
    return true;
}

MAIN:{
    srand(121);
    my $aig = new AI::Genetic(
        -fitness    => \&fitness,
        -type       => "rangevector",
        -population => 500,
        -crossover  => 0.9,
        -mutation   => 0.1,
    );
    my $genes = [];
    for (0 .. N + 1){
        push @{$genes}, [0, N];
    }
    @matrix = ();
    for (0 .. N){
        my $row = [];
        for my $i (0 .. N){
            push @{$row}, int(rand(N * 2 + 1));
        }
        push @matrix, $row;
    }
    $aig->init(
        $genes
    );
    $aig->evolve("tournamentUniform", 100000);
    my $path = $aig->getFittest()->genes();
    print join(",", @{$path}) . "\n";
    my $cost;
    for my $i (0 .. @{$path} - 2){
        $cost += $matrix[$path->[$i]][$path->[$i + 1]];
    }
    print "cost: $cost\n";
}

Sample Run


$ perl perl/ch-2.pl
3,0,1,2,3
cost: 10
$ perl perl/ch-2.pl
3,1,7,5,4,6,0,2,3
cost: 24

Notes

I have used Genetic Algorithm (GA) approaches to a bunch of these challenge problems in the past. I will admit that in some cases the GA approach is more for fun than as a good example of the sorts of problems GA is good for. This time, however, we have a somewhat classic use case!

The Travelling Salesman Problem is well known to be NP-Hard and Genetic Algorithms are a well studied approach to tackling these beasts.

I first tested this solution with the example in the original problem statement, hardcoded here in @matrix and obtained a result which matched the known correct one. Then, testing with increasingly larger values of N to generate random matrices I continued to get seemingly correct results. I did not verify these by hand. Instead I set a random seed with srand and verified that I got the same cost results over several runs. As needed I would adjust the number of generations in the evolve() method call upwards until again getting results which converged on the same cost value.

For a 20 x 20 matrix I seem to be getting correct results, but runtimes are quite lengthy and I ran out of time to test this further. However, I am very confident that a correct path is obtainable this way although perhaps some additional slight adjustment of parameters is necessary.

(Hopefully nobody is too terribly confused by this, but please do notice that the size of the matrix is actually N + 1. That is, in order to obtain a matrix like the one given in the problem statement you specify an N of 3, although obviously this is a 4 x 4 matrix. This is just in keeping with the city labels starting with 0.)

References

Challenge 121

(cccl) 9 great CPAN modules released last week

Niceperl

Published by Unknown on Saturday 17 July 2021 20:21

Updates for great CPAN modules released last week. A module is considered great if its favorites count is greater or equal than 12.

  1. App::Netdisco - An open source web-based network management tool.
    • Version: 2.047007 on 2021-07-14
    • Votes: 13
    • Previous version: 2.047005 was 4 months, 18 days before
  2. FFI::Platypus - Write Perl bindings to non-Perl libraries with FFI. No XS required.
    • Version: 1.53 on 2021-07-12
    • Votes: 54
    • Previous version: 1.52 was 11 days before
  3. Future::AsyncAwait - deferred subroutine syntax for futures
    • Version: 0.52 on 2021-07-13
    • Votes: 39
    • Previous version: 0.51 was 1 month, 13 days before
  4. Net::DNS - Perl Interface to the Domain Name System
    • Version: 1.32 on 2021-07-16
    • Votes: 21
    • Previous version: 1.31 was 2 months, 14 days before
  5. Object::Pad - a simple syntax for lexical slot-based objects
    • Version: 0.44 on 2021-07-15
    • Votes: 15
    • Previous version: 0.43 was 12 days before
  6. Paws - A Perl SDK for AWS (Amazon Web Services) APIs
    • Version: 0.44 on 2021-07-14
    • Votes: 48
    • Previous version: 0.43 was 2 months, 8 days before
  7. Perl::Tidy - indent and reformat perl scripts
    • Version: 20210717 on 2021-07-17
    • Votes: 121
    • Previous version: 20210625 was 23 days before
  8. Test::Warnings - Test for warnings and the lack of them
    • Version: 0.031 on 2021-07-13
    • Votes: 15
    • Previous version: 0.030 was 1 year, 3 months, 23 days before
  9. TheSchwartz - reliable job queue
    • Version: 1.16 on 2021-07-16
    • Votes: 13
    • Previous version: 1.15 was 1 year, 5 months, 19 days before

(cdlxxvi) metacpan weekly report - Object::Pad

Niceperl

Published by Unknown on Saturday 17 July 2021 20:14

This is the weekly favourites list of CPAN distributions. Votes count: 43

Week's winner: Object::Pad (+3)

Build date: 2021/07/17 18:13:49 GMT


Clicked for first time:


Increasing its reputation:

Ann Barcomb study: Survey launch

Perl Foundation News

Published by Nic Evans on Thursday 15 July 2021 03:49

Published on behalf of TPF Board.

(Dr. Ann Barcomb)[https://barcomb.org] of the University of Calgary is conducting research to understand episodic, or occasional, participation in the Perl and Raku communities, in collaboration with The Perl Foundation. The results of the research will be provided as a TPF report and will assist the community in improving practices for managing episodic participation to provide insights into what free / libre / open source software projects could do to become more sustainable.

If you would like to take part in this study, click here to access the survey. Based on pilot testing, this survey is expected to take about 15 minutes to complete (there are 41 questions in this survey). Participation in this study is anonymous. By completing the survey, you are agreeing to have your responses included in the study.

We thank Ann for selecting our communities as the subject of this research. We expect that this work will be beneficial to our communities as well as others. And we thank you in advance for contributing to this research. Your input is much appreciated.

The University of Calgary Conjoint Faculties Research Ethics Board has approved this study (REB20-2135).

perlbrew

Perl-Academy.de

Published on Wednesday 14 July 2021 10:00

Das System-Perl zu verwenden hat viele Nachteile. Diese können behoben werden, wenn man ein eigenes Perl in seinem Benutzerverzeichnis installiert. Mit dem Werkzeug `perlbrew` kannst du mehrere Perl-Installationen nebeneinander auf einem System konfliktfrei betreiben.

Grant Proposal: Maintaining Perl 5 Core (Dave Mitchell)

Perl Foundation News

Published by Jason A. Crome on Tuesday 13 July 2021 22:32

Synopsis

This application is to extend into the future the TPF grant funding I have been receiving over the last ten years or so to maintain the Perl core. I'm one of the main maintainers of the Perl core internals, and new funding will help me to continue working on the core.

Project Details

This project will cover improvements to the perl core such as: general maintenance, bug fixes, performance issues, new features, investigating smoke failures, helping getting Perl into a releasable state etc. These are all activities I already do.

Timeline

There is no particular schedule. I am available to start immediately. As and when I can put hours in, I will charge for those hours. This is the same as the current arrangements.

Author Information

Dave Mitchell

I'm a freelance programmer and UNIX sysadmin living in the UK. I have been using Perl since 1993, and have been fixing core Perl 5 bugs since 2001. I have had commit rights since 2003 and I was responsible for the 5.10.1 and 5.14.4 perl releases. I am known for fixing "hard" things in the Perl core.

Endorsed By

Ricardo Signes, Nicolas Rochelemagne

Amount Requested

$60 per hour, to a total of $21,000 [I've suggested an amount divisible by 60 to make things easier]. A smaller or larger total amount is acceptable, as I'm assuming that, as before, I will be able to apply for extensions to the grant.

Call for Grants: July 2021 Round

Perl Foundation News

Published by Jason A. Crome on Tuesday 13 July 2021 22:26


The Grants Committee is accepting grant proposals all the time. We evaluate them every two months and another round is starting.

If you have an idea for doing some work that will benefit the Perl or Raku communities, please consider submitting a grant application. The application deadline for this round is 23:59 July 27, 2021, UTC. We will publish the received applications, get community feedback through August 3rd, and we will conclude the process shortly thereafter.

We now accept grant requests for core Perl and Raku development. There are some eligibility requirements that must be met for each language when submitting a grant. For Perl: * The applicant must be a contributor to the Perl core. * The application must be endorsed by one or more people with commit rights to the Perl core.

For Raku: * The applicant must be a contributor to the Raku language specification or one of its implementations. * The application must be endorsed by one or more people in Raku Steering Council.

For more information, see this blog post.

To apply, please read How to Write a Proposal, GC Charter, Rules of Operation and Running Grants List will also help you understand how the grant process works. We also got some grant ideas from the community. Grant applications may be submitted via this Google Form.

We will confirm the receipt of application by August 4th.

If you have further questions, please contact me at tpf-grants-secretary at perl-foundation.org.

Maintaining Perl 5 (Dave Mitchell): May /June 2021 Report

Perl Foundation News

Published by Matthias Bloch on Tuesday 13 July 2021 03:23

This is a monthly report by Tony Cook on his Maintaining Perl 5 grant. We thank the TPF sponsors to make this possible.

``` Did very little work in May

  2:39 process p5p mailbox  
------
  2:39 TOTAL (HH::MM) 

```

``` In June I made a start on catching up on many months of unread p5p emails, github notifications etc.

SUMMARY: 10:46 process p5p mailbox ------ 10:46 TOTAL (HH::MM)

There are 28.7 hours left on the existing grant, (but I've applied for a new grant). ```

#520 - CPAN Bus Factor

Perl Weekly

Published on Monday 12 July 2021 10:00

Hi there

If, like me, you are a fan of MetaCPAN then you must have noticed the latest changes to the MetaCPAN site. It is the introduction of new metric, "CPAN Bus Factor". Don't know what I am talking about? Well then you should read the blog post, which is a collaborative work by Neil Bowers and Olaf Alders.

It reminds me an incident from the past when I received an email from Neil Bowers about one of my CPAN distribution, IP::Info as he was reviewing CPAN modules for locating an IP address. Later he published his report on 8th Aug 2012. You can take a look collection of CPAN module reviews by him. If my memory serves, Neil also ran CPAN Weekly, for a while. I did join the mailing list and the received CPAN Weekly newsletter talking about a CPAN module and its usage every week. Unfortunately it is no longer active.

A long time ago, I used to be an active CPAN contributor. Unfortunately, because of time constraints, I'm no longer as active as I used to be. I even wrote a two-part blog post on the subject - "How to become a CPAN contributor?" - for perl.com in 2018. You can check out the posts, Part 1 and Part 2, if you are interested.

Why am I talking about CPAN contributions?

A friend of mine and fellow contributor to The Weekly Challenge, Cheok-Yin Fung, wrote a blog about her experience of uploading her first distribution to CPAN. It reminds me of my early days of struggle with CPAN. These days there is a lot of help available on various public platforms. I wish her all the best and welcome to the club of CPAN contributors.

I came across a very interesting blog post by JJ Merelo talking about Pull Request do's and don'ts. Very helpful advice for anyone looking to contribute to open source projects in general.

Enjoy the rest of the newsletter.

Swapping Bits / Time Angle

RabbitFarm Perl

Published on Sunday 11 July 2021 17:41

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

Part 1

You are given a positive integer $N less than or equal to 255. Write a script to swap the odd positioned bits with the even positioned bits and print the decimal equivalent of the new binary representation.

Solution


use strict;
use warnings;
sub swap_bits{
    my($n) = @_;
    my $bits = substr(unpack("B32", pack("N", shift)), 24, 8);
    my @bits = split(//, $bits);
    for(my $i = 0; $i < @bits; $i += 2){
        @bits[$i, $i + 1] = @bits[$i + 1, $i]; 
    }  
    my $swapped_decimal = unpack("N", pack("B32", substr("0" x 32 . join("", @bits), -32)));
    return $swapped_decimal; 
}

MAIN:{
    my $N;
    $N = 101; 
    print swap_bits($N) . "\n";
    $N = 18; 
    print swap_bits($N) . "\n";
}   

Sample Run


$ perl perl/ch-1.pl
154
33

Notes

This code re-uses much of the code from last week's challenge solution. The only difference here is the for loop which swaps the even/odd bits.

Part 2

You are given time $T in the format hh:mm. Write a script to find the smaller angle formed by the hands of an analog clock at a given time.

Solution


use strict;
use warnings;
sub clock_angle{
    my($h, $m) = split(/:/, $_[0]);
    my $angle = abs(0.5 * (60 * $h - 11 * $m)); 
    $angle = 360 - $angle if $angle > 180; 
    return $angle;
}

MAIN:{
    my $T;
    $T = "03:10";  
    print clock_angle($T) . "\n";  
    $T = "04:00";  
    print clock_angle($T) . "\n";  
}

Sample Run


$ perl perl/ch-1.pl
35
120

Notes

Perhaps not a whole lot going on here: the time is broken into hour and minute parts and then the angle is computed directly from those values.

References

Challenge 120

Outreachy Internship - Rosheen working on Open Food Facts

Perl Foundation News

Published by Makoto Nozaki on Monday 05 July 2021 12:47

I am pleased to announce we accepted an intern, Rosheen Naeem, to this year’s Outreachy internship at Open Food Facts. Rosheen will work with Stéphane Gigandet on a project to improve the quality (templatization, documentation, unit tests etc.) of the Open Food Facts backend (all written in Perl) to make it more friendly to new developers until August 2021.

Rosheen is a software engineer based in Pakistan. She has expertise in web development and technical writing. She brings with herself experience in web development, opensource, game development, and technical course designing.

Rosheen’s contributions can be seen at openfoodfacts Github repository. Rosheen also published her experience with the Outreachy selection process in her Medium article.

Open Food Facts is a free, online and crowdsourced database of food products from around the world. Product data and photos are contributed through the Open Food Facts mobile application or sent by food manufacturers. Open Food Facts then analyze the ingredients, nutrition facts, labels, and packaging of products to compute nutritional or environmental scores such as the Nutri-Score and the Eco-Score.

Please join me in welcoming Rosheen to the Perl & Raku community.

P.S. We also gave a talk on our summer activities at the Perl & Raku Conference including Outreachy, Google Season of Docs and Google Summer of Code.

#519 - Crystal conference and course

Perl Weekly

Published on Monday 05 July 2021 10:00

Hi there!

I am going to give a presentation at the Crystal 1.0 conference alongside Yukihiro 'Matz' Matsumoto and Bruce Perens (just to throw in two names you might be familiar with and to have some honor by association). It is taking place this Thursday. It is my first presentation at an international conference for a long time. Wish me luck!

If you cannot make it to the conference, but you are interested in learning Crystal, I am going to start an experimental programming Crystal course via Zoom. You can get more information and register here

As for Perl, it was a rather quiet week without a lot of posts, but still there is some nice stuff in here

Enjoy your week!

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

Part 1

You are given a positive integer $N. Write a script to swap the two nibbles of the binary representation of the given number and print the decimal number of the new binary representation.

Solution


use strict;
use warnings;
sub swap_nibbles{
    my($n) = @_;
    my $bits = substr(unpack("B32", pack("N", shift)), 24, 8);
    my $swapped_bits = substr($bits, 4) . substr($bits, 0, 4);
    my $swapped_decimal = unpack("N", pack("B32", substr("0" x 32 . $swapped_bits, -32)));
    print $swapped_decimal . "\n";
}

MAIN:{
    swap_nibbles(101);
    swap_nibbles(18);
}

Sample Run


$ perl perl/ch-1.pl
86
33

Notes

I was on vacation recently and did not have time for the last couple of Weekly Challenges, but as I posted a meme about it is hard to take a break!

(The Perl Programmers Facebook group is a lof of fun. It is kept Private by the group owner but joining is easy, anyone is allowed provided they are interested in Perl.)

I was able to get through the first part of this week's challenge with the time I had after getting back from vacation. As I was unpacking my suitcase, co-incidentally enough, I noticed that the first task is a great use of pack and unpack!

I have used these functions several times in the past, for example this writeup from Challenge 020 has an example and some links to others. I must admit that from the earliest days of my Perl experience I have been fascinated by pack! At first it seemed like a bit of black magic and due to its versatility, in some ways it still retains this mystique.

In the swap_nibbles function the number is packed into Network Byte Order and that representation is that unpacked bitwise to get the expected binary representation. After that the two nibbles are swapped using substr to get each 4 bit slice. The process is then reversed on the swapped bits to get the result we want.

References

Challenge 119

Network Byte Order

Perl Programmers Facebook Group

List of new CPAN distributions – Jun 2021

Perlancar

Published by perlancar on Thursday 01 July 2021 01:24

dist author first_version latest_version abstract
Acme-CPANModules-OrganizingCPAN PERLANCAR 0.001 0.001 Efforts to organize CPAN
Acme-CPANModules-RandomData PERLANCAR 0.001 0.002 Generating random person (name, title, age, etc)
Acme-CPANModules-RandomPassword PERLANCAR 0.001 0.001 Generating random passwords
Acme-CPANModules-RandomPerson PERLANCAR 0.001 0.001 Generating random person (name, title, age, etc)
Acme-ELLEDNERA-Utils ELLEDNERA 0.01 0.04 Done for the sake of learning 🙂
Acme-MetaSyntactic-boboiboy PERLANCAR 0.001 0.001 The BoboiBoy theme
Acme-MetaSyntactic-ozark PERLANCAR 0.001 0.001 The Ozark theme
Acme-PERLANCAR-Dummy PERLANCAR 0.001 0.001 Dummy distribution for various testing
Acme-Version-Negative CONTRA 0 Module for testing CPAN Pause indexing
Acme-Version-Regress CONTRA 5.00 3.00 Module for testing CPAN Pause indexing
Acme-Version-utf8 CONTRA Module for testing CPAN Pause indexing
Alien-Build-Plugin-Extract-Libarchive PLICEASE 0.01 0.01 Alien::Build plugin to extract a tarball using libarchive
Alien-SNMP-MIBDEV INPHOBIA 2.000000 2.000000 Build and install Net-SNMP
Alien-Wslay EGOR 0.1 0.1 Discover or download and install Wslay
Amp-Client RES 0.03 0.03 Blah blah blah
App-Bin4TSV-6 TULAMILI 0.090 0.090 pattern searcher given which column to seek together with regular expression
App-Bin4TSV-8 TULAMILI 0.100 0.101
App-Bin4TSV-9 TULAMILI 0.110 0.111
App-Dex SYMKAT 0.002000 0.002000 Directory Execute
App-EPAN POLETTIX 0.001 0.002 Exclusive Perl Archive Nook
App-IODCounterSimpleUtils PERLANCAR 0.001 0.001 CLI utilities for IOD::Counter::Simple
App-PMVersionsUtils PERLANCAR 0.001 0.001 CLI utilities related to PMVersions
App-SQLiteCounterSimpleUtils PERLANCAR 0.001 0.002 CLI utilities for SQLite::Counter::Simple
App-SQLiteKeyValueStoreSimpleUtils PERLANCAR 0.001 0.001 CLI utilities for SQLite::KeyValueStore::Simple
App-Stow-Check SKIM 0.01 0.02 Distribution for stow-check script.
App-arraydata PERLANCAR 0.001 0.003 Show content of ArrayData modules (plus a few other things)
App-colgrep TULAMILI 0.100 0.100 pattern searcher given which column to seek together with regular expression
App-colsummary TULAMILI 0.050 0.058
App-crosstable TULAMILI 0.100 0.110 Produce the crosstable from the 2 column data. Can also sum up a additional column by -3 switch option.
App-csel TULAMILI 0.100 0.120
App-digitdemog TULAMILI 0.050 0.050
App-expandtab TULAMILI 0.010 0.020
App-freq TULAMILI 0.100 0.120
App-podman PEVANS 0.01 0.01 a terminal document viewer for POD and other syntaxes
App-sdview PEVANS 0.01 0.02 a terminal document viewer for POD and other syntaxes
App-tabledata PERLANCAR 0.001 0.001 Show content of TableData modules (plus a few other things)
App-traveller SCHROEDER 1 1.01 a webserver that serves Traveller RPG maps
App-venn TULAMILI 0.100 0.120
App-zoo CCCACHE 0.01 0.02 print bar, usually
Archive-Libarchive-Unwrap PLICEASE 0.01 0.01 Unwrap files with multiple compression / encoding formats
Astro-FITS-CFITSIO-FileName DJERIUS 0.01 0.05 parse and generate CFITSIO extended file names.
Bencher-Scenario-Perl-Startup PERLANCAR 0.051 0.051 Benchmark startup time of perls
CSS-Struct-Output-Structure SKIM 0.01 0.02 Indent printing 'CSS::Struct' structure to CSS code.
Catalyst-Plugin-PrometheusTiny SYSPETE 0.001 0.006 Prometheus metrics for Catalyst
Cfwp-fio CCCACHE v0.0.4 0.04
Cfwp-zoo CCCACHE v0.0.1 0.01 print bar, usually
ColorTheme-Search-Light PERLANCAR 0.001 0.001 Light theme for text viewer/search application
Compress-LZString POPP 1.44 1.4401 LZ-based compression library
Dancer2-Plugin-PrometheusTiny SYSPETE 0.001 0.005 Prometheus metrics for Dancer2
DataStructure MATHIAS 0.01 0.01 Collection of useful data-structures in pure Perl
Devel-Deanonymize TOBIB v0.1.0 v0.1.1 A tool do make anonymous sub visible to Devel::Cover
Device-Chip-MAX44009 PEVANS 0.01 0.02 chip driver for MAX44009
Device-Chip-OPT3001 PEVANS 0.01 0.01 chip driver for OPT3001
Dist-Zilla-PluginBundle-Author-ASDAGO ASDAGO 0.001 0.001 ASDAGO's Dist::Zilla plugin bundle
Dist-Zilla-PluginBundle-Author-VNEALV VNEALV 0.001 0.002 A plugin bundle for distributions config as common dist.ini by VNEALV
Geo-H3 MRDVT 0.03 0.06 H3 Geospatial Hexagon Indexing System
Geo-H3-FFI MRDVT 0.02 0.06 Perl FFI binding to H3 library functions
Graph-Undirected-Hamiltonicity ASHWIN 0.1 0.1 decide whether a given Graph::Undirected contains a Hamiltonian Cycle.
Hustle-Table DRCLAW v0.1 v0.2.2 Fast dynamic dispatching to subroutines
IOD-Counter-Simple PERLANCAR 0.001 0.002 A simple counter using IOD/INI file
Imager-IMBarcode-JP TANIGUCHI 0.01 0.01 Japan's Intelligent Mail Barcode Generator
JSON-Schema-Modern ETHER 0.512 0.513 Validate data against a schema
LINE-Notify-Simple HOLLY 1.0 1.02
List-Util-Find PERLANCAR 0.001 0.003 List utilities related to finding items
Module-Features-Dummy PERLANCAR 0.001 0.004 Dummy feature set, for testing
Mojolicious-Plugin-Obrazi BEROV 0.11 0.12 a gallery generator command
Net-Async-Spotify VNEALV 0.001 0.001 Interaction with spotify.com API
Net-Payment-CCAvenue-NonSeamless SHARDIWAL 0.01 0.02 Processing orders using CCAvenue billing page!
Net-WebSocket-EVx EGOR 0.12 0.18 Perl wrapper around Wslay websocket library
PLS MREISNER 0.1 0.8 Perl Language Server
Plack-App-Redirect SKIM 0.01 0.01 Plack application for redirection.
Plack-Middleware-TrafficAdvice RRWO v0.1.0 v0.2.1 handle requests for /.well-known/traffic-advice
Pod-PseudoPod-Book CHROMATIC 1.20210620.2051 1.20210620.2051 manages books written in the Pod::PseudoPod format
Pod-PseudoPod-DOM CHROMATIC 1.20210620.2004 1.20210620.2040 an object model for Pod::PseudoPod documents
Pod-Simple-Words PLICEASE 0.07 0.07 Parse words and locations from a POD document
Promise-Me JDEGUEST v0.1.0 v0.1.1 Fork Based Promise with Asynchronous Execution, Async, Await and Shared Data
Require-Util PERLANCAR 0.001 0.001 Utilities related to require()
SDL2 SANKO 0.01 0.01 FFI Wrapper for SDL (Simple DirectMedia Layer) Development Library
SQLite-Counter-Simple PERLANCAR 0.001 0.003 A simple counter using SQLite
SQLite-KeyValueStore-Simple PERLANCAR 0.001 0.002 A simple key-value store using SQLite
Sah-Schemas-ArrayData PERLANCAR 0.001 0.001 Sah schemas related to ArrayData
Sah-Schemas-TableData PERLANCAR 0.001 0.001 Sah schemas related to TableData
Script-Singleton STEVEB 0.01 0.01 Ensure only a single instance of a script can run
String-Trim-NonRegex PERLANCAR 0.001 0.002 String trimming functions that do not use regex
String-Trim-Regex MBURGER 20210604 20210604 Trims the spaces off the leading / trailing string.
Syntax-Keyword-Combine-Keys LNATION 0.01 0.09 The great new Syntax::Keyword::Combine::Keys!
TableData-Locale-US-State PERLANCAR 20200531.0.1 20200531.0.1 US states
TableData-Quote-JamesFT PERLANCAR 0.002 0.002 Quotes from JamesFT github repository
TableDataBundle-Lingua-Word-EN-Adjective PERLANCAR 0.002 0.002 Collection of TableData:: modules that contain English adjectives
TableDataBundle-Lingua-Word-EN-Adverb PERLANCAR 0.002 0.002 Collection of TableData:: modules that contain English adverbs
TableDataBundle-Lingua-Word-EN-Noun PERLANCAR 0.002 0.002 Collection of TableData:: modules that contain English nouns
Tags-HTML-GradientIndicator SKIM 0.01 0.02 Tags helper for gradient evaluation.
Text-HumanComputerWords PLICEASE 0.04 0.04 Split human and computer words in a naturalish manner
Text-Wrap-OO ASDAGO 0.001 0.002 an object oriented interface to Text::Wrap
Time-Local-More PERLANCAR 0.001 0.001 More functions for producing Unix epoch timestamp or localtime/gmtime tuple
ToolSet-Math GLAI 1.001 1.001 Bring in common math functions and constants.
Tree-Multi PRBRENAN 20210528 20210629 Multi-way tree in Pure Perl
Tree-Serial SLITTL 0.1 0.2 Perl module for deserializing lists of strings into tree-like structures
Tree-Term PRBRENAN 20210629 20210631 Create a parse tree from an array of terms representing an expression.
Type-Tie-Aggregate ASDAGO 0.001 0.001 like Type::Tie, but slower and more flexible
cfwp-fio CCCACHE v0.0.1 v0.0.3
custom-failures-x-alias DJERIUS 0.01 0.02 export aliases for custom::failures
mb-Encode INA 0.01 0.01 provides MBCS encoder and decoder
perleasyfail PERLANCAR 0.000001 0.000002 A collection of cases where core Perl fails its "easy things should be easy" mantra (plus their remedies)

Stats

Number of new CPAN distributions this period: 104

Number of authors releasing new CPAN distributions this period: 41

Authors by number of new CPAN distributions this period:

No Author Distributions
1 PERLANCAR 31
2 TULAMILI 11
3 PEVANS 4
4 PLICEASE 4
5 SKIM 4
6 CCCACHE 4
7 ASDAGO 3
8 CONTRA 3
9 VNEALV 2
10 CHROMATIC 2
11 PRBRENAN 2
12 EGOR 2
13 SYSPETE 2
14 MRDVT 2
15 DJERIUS 2
16 RRWO 1
17 DRCLAW 1
18 INPHOBIA 1
19 TOBIB 1
20 ETHER 1
21 GLAI 1
22 LNATION 1
23 INA 1
24 SCHROEDER 1
25 RES 1
26 SHARDIWAL 1
27 MATHIAS 1
28 STEVEB 1
29 BEROV 1
30 MBURGER 1
31 SANKO 1
32 ELLEDNERA 1
33 TANIGUCHI 1
34 MREISNER 1
35 SYMKAT 1
36 SLITTL 1
37 POLETTIX 1
38 HOLLY 1
39 ASHWIN 1
40 POPP 1
41 JDEGUEST 1