FLOSS Project Planets

Git Alligator

Planet KDE - Thu, 2019-08-08 18:00

This is a short description of a workflow I apply in git repositories that I “own”; it mostly gets applied to Calamares, the Linux installer framework, because I spend most of my development hours on that. But it also goes into ARPA2 projects and home experiments.

It’s a variation on “always summer in master”, and I call it the Git Alligator because when you draw the resulting tree in ASCII-art, horizontally (I realise that’s a pretty niche artform), you get something like this:

/-o-o-\ /-o-o-o-\ /-o-\ o--o-------o-o---------o-----o--o

To me, that looks like the bumps on an alligator’s back. If I were a bigger fan of Antoine de Saint-Exupéry, I would probably see it as a python that has eaten multiple elephants.

Anyway, the idea is twofold:

  • master is always in a good state
  • I work on (roughly) one thing at a time

For each thing that I work on, I make a branch; if it’s attached to a Calamares issue, I’ll name it after the issue number. If it’s a different bit of work, I’ll name it more creatively. The branch is branched off of master (which is always in a good state). Then I go and work on the branch – commit early, commit often – until the issue is resolved or the feature implemented or whatever.

In a codebase where I’m the only contributor, or the gatekeeper for it so that I know that master remains unchanged, I know a merge can go in painlessly. In a codebase with more contributors, I might merge upstream master into my branch right at the end as a sanity check (right at the end because most of these branches are short-lived, a day or two at most for any given issue).

The alligator effect comes in when merging back to master: I always use --no-ff and I try to write an additional summary description of the branch in the merge commit.

Here’s a screenshot of Calamares history, from qgit, turned on its side like an alligator crawling to the right, (cropped a little so you don’t see where I don’t follow my own precepts and annotated with branch names).

Aside from the twofold ideas of “always summer in master” and “focus on one thing” I see a couple of other benefits:

  • History if desired; this approach preserves history (all the little steps, although I do rebase and fixup and amend stuff as I go along, I don’t materially squash things).
  • Conciseness when needed; having all the history is nice, but if you follow the “alligator’s tummy branch” (that is, master, along the bottom of the diagrams) you get only merge nodes with a completed bugfix or feature and a little summary: in other words, following that line of commits gives you a squashed view of what happened.
  • Visual progress; each “bump” on the alligator’s back is a unit of progress. If I were to merge without --no-ff the whole thing would be smooth like a garter snake, and then it’s much harder to see the “things” that I’ve done. Instead I’d need to look at the log and untangle commit messages to see what I was working on. This has a “positivity” benefit: I can point and say “I did a thing!”

I won’t claim this approach works for everybody, or for larger teams, but it keeps me happy most days of the week, and as a side benefit I get to think about ol’ Albert the Alligator.

Categories: FLOSS Project Planets

Finally, I’m back… more or less

Planet KDE - Thu, 2019-08-08 16:38
…and I’ve made a new wallpaper!

Yes, finally i’m back on my favourite application, Inkscape.

Hope this is a cool presentation 

I called this wallpaper Mountain, because … well, there are mountains with a sun made with the KDE Neon logo. hope you like it

See you soon with other wallpapers …

 

 

Categories: FLOSS Project Planets

Hook 42: Drupal Core Initiative Meetings Recap - August 5th - 9th, 2019

Planet Drupal - Thu, 2019-08-08 15:12
Drupal Core Initiative Meetings Recap - August 5th - 9th, 2019 Will Thurston-… Thu, 08/08/2019 - 19:12
Categories: FLOSS Project Planets

Mediacurrent: Composer-Patches: The Dependency You Never Knew You Needed

Planet Drupal - Thu, 2019-08-08 11:49

For most Drupal projects, patches are inevitable. It’s how we, in the Drupal community, share code. If that scares you, don’t worry-- the community is working hard to move to a pull/merge request workflow. Due to the collaborative nature of Drupal as a thriving open source community and the always growing ecosystem of contrib modules, patches are the ever-evolving glue that can hold a site together.  

Before Drupal 8, you may have seen projects use drush make which is a Drupal specific solution. As part of the “get off the island” movement,  Drupal adopted existing dependency manager Composer. Composer does a decent job alleviating the headaches of managing several sites with different dependencies. However, out of the box Composer will revert patched core files and contrib modules and it is for that reason composer-patches project was created. In this blog post, we are going to review how to set up composer-patches for a composer managed project and how to specify local or remote hosted patches.

The setup

In your favorite command line tool, you will want to add the composer-patches project:

composer require cweagans/composer-patches:~1.0 --update-with-dependencies

With this small change, your project is now set up for success because composer can manage your patches. 

Local patches

Sometimes you will find that you need patch contrib or core specifically for your project and therefore the patch exists locally. Composer-patches can apply that patch for you, we just need to tell it where it is.  Let’s look at an example project that has core patch applied and saved locally in the project root directory ‘patches/core-invalid-config-structures.patch’:
    ...
    "extra": {
      "patches": {
        "drupal/core": {
          "Core Invalid config structures ":"patches/core-invalid-config-structures.patch"
        }
      }
    }

In your composer.json, you will want to add an “extra” section if it doesn’t already exist.  Composer-patches will take the packages listed in “patches” and try to apply any listed patches. In our above example, the package we are patching is “drupal/core”. Patches are declared as follows:

“Patch description”: “path to patch file”

This information will be printed on the command line while composer tries to update the package which makes it important to summarize the patches purpose well.  If you would like to see what this looks like in the wild, take a look at our distribution Rain which leverages a couple of contrib patches.

After manually updating composer.json, it is always a good idea to run composer validate to confirm the json syntax is right.  If you get the green success message run composer update drupal/[projectname], e.g. composer update drupal/core to have the patch applied. 

You will know that the patch is applied based on the output:

As you can see, the package getting patched is removed, added back and the patch is applied. 

Note: Sometimes I feel like I have to give composer a nudge, always feel comfortable deleting /core, /vendor, or /modules/contrib, but if you delete composer.lock know that your dependencies could update based off your constraints.  Composer.json tracks our package dependencies at certain version constraints while composer.lock is the recipe of computed versions based off those constraints. I have found myself running the following:

rm -rf core && rm -rf modules/contrib && rm -rf vendor
composer install

Remote Patches

When possible we should open issues on Drupal.org and post patches there. That way, the community can work together to solve a problem and usually you’ll get a more reliable, lasting solution. Think about it this way - would you rather only you or your team review a critical patch to your project or hundreds of developers?

To make composer-patches grab a remote patch make the following changes:
    ...
    "extra": {
      "patches": {
        "drupal/core": {

          "#2925890-10: Invalid config structures ":"https://www.drupal.org/files/issues/2018-09-26/2925890-10.patch"
        }
      }
    } 

The only change here is rather than the path to the local patch, we have substituted it for the URL the patch. This will have a similar success message when applied correctly:

Tips 

So far, I’ve shown you how to get going with composer-patches project but there are a lot of settings/plugins that can elevate your project.  A feature I turn on for almost all sites is exit on patch failure because it is a big deal when a patch fails.  If you too want to turn this feature on, add the following line to your “extras” section in your composer.json:

"composer-exit-on-patch-failure": true,

I have also found it helpful to add a link back to the original issue in the composer.json patch declaration. Imagine working on a release and one of your patches fail but the only reference you have to the issue is the patch file url? It is times like these that a link to the issue can make your day.  If we made the same change to our example before, it would look like the following:

 "drupal/core": {
          "#2925890-10: Invalid config structures (https://www.drupal.org/project/drupal/issues/2925890)" : "https://www.drupal.org/files/issues/2018-09-26/2925890-10.patch"
        }

Conclusion

Composer-patches is a critical package to any Drupal project managed by Composer. In this blog I showed you how to get started with the project and some of the tips and tricks I’ve learned along the way. How does your team user composer-packages? Do you have a favorite setting that I didn’t mention? Feel free to drop a comment and share what works for you and your team.

Categories: FLOSS Project Planets

Mediacurrent: Composer-Patches: The Dependency You Never Knew You Needed

Planet Drupal - Thu, 2019-08-08 11:49

For most Drupal projects, patches are inevitable. It’s how we, in the Drupal community, share code. If that scares you, don’t worry-- the community is working hard to move to a pull/merge request workflow. Due to the collaborative nature of Drupal as a thriving open source community and the always growing ecosystem of contrib modules, patches are the ever-evolving glue that can hold a site together.  

Before Drupal 8, you may have seen projects use drush make which is a Drupal specific solution. As part of the “get off the island” movement,  Drupal adopted existing dependency manager Composer. Composer does a decent job alleviating the headaches of managing several sites with different dependencies. However, out of the box Composer will revert patched core files and contrib modules and it is for that reason composer-patches project was created. In this blog post, we are going to review how to set up composer-patches for a composer managed project and how to specify local or remote hosted patches.

The setup

In your favorite command line tool, you will want to add the composer-patches project:

composer require cweagans/composer-patches:~1.0 --update-with-dependencies

With this small change, your project is now set up for success because composer can manage your patches. 

Local patches

Sometimes you will find that you need patch contrib or core specifically for your project and therefore the patch exists locally. Composer-patches can apply that patch for you, we just need to tell it where it is.  Let’s look at an example project that has core patch applied and saved locally in the project root directory ‘patches/core-invalid-config-structures.patch’:
    ...
    "extra": {
      "patches": {
        "drupal/core": {
          "Core Invalid config structures ":"patches/core-invalid-config-structures.patch"
        }
      }
    }

In your composer.json, you will want to add an “extra” section if it doesn’t already exist.  Composer-patches will take the packages listed in “patches” and try to apply any listed patches. In our above example, the package we are patching is “drupal/core”. Patches are declared as follows:

“Patch description”: “path to patch file”

This information will be printed on the command line while composer tries to update the package which makes it important to summarize the patches purpose well.  If you would like to see what this looks like in the wild, take a look at our distribution Rain which leverages a couple of contrib patches.

After manually updating composer.json, it is always a good idea to run composer validate to confirm the json syntax is right.  If you get the green success message run composer update drupal/[projectname], e.g. composer update drupal/core to have the patch applied. 

You will know that the patch is applied based on the output:

As you can see, the package getting patched is removed, added back and the patch is applied. 

Note: Sometimes I feel like I have to give composer a nudge, always feel comfortable deleting /core, /vendor, or /modules/contrib, but if you delete composer.lock know that your dependencies could update based off your constraints.  Composer.json tracks our package dependencies at certain version constraints while composer.lock is the recipe of computed versions based off those constraints. I have found myself running the following:

rm -rf core && rm -rf modules/contrib && rm -rf vendor
composer install

Remote Patches

When possible we should open issues on Drupal.org and post patches there. That way, the community can work together to solve a problem and usually you’ll get a more reliable, lasting solution. Think about it this way - would you rather only you or your team review a critical patch to your project or hundreds of developers?

To make composer-patches grab a remote patch make the following changes:
    ...
    "extra": {
      "patches": {
        "drupal/core": {

          "#2925890-10: Invalid config structures ":"https://www.drupal.org/files/issues/2018-09-26/2925890-10.patch"
        }
      }
    } 

The only change here is rather than the path to the local patch, we have substituted it for the URL the patch. This will have a similar success message when applied correctly:

Tips 

So far, I’ve shown you how to get going with composer-patches project but there are a lot of settings/plugins that can elevate your project.  A feature I turn on for almost all sites is exit on patch failure because it is a big deal when a patch fails.  If you too want to turn this feature on, add the following line to your “extras” section in your composer.json:

"composer-exit-on-patch-failure": true,

I have also found it helpful to add a link back to the original issue in the composer.json patch declaration. Imagine working on a release and one of your patches fail but the only reference you have to the issue is the patch file url? It is times like these that a link to the issue can make your day.  If we made the same change to our example before, it would look like the following:

 "drupal/core": {
          "#2925890-10: Invalid config structures (https://www.drupal.org/project/drupal/issues/2925890)" : "https://www.drupal.org/files/issues/2018-09-26/2925890-10.patch"
        }

Conclusion

Composer-patches is a critical package to any Drupal project managed by Composer. In this blog I showed you how to get started with the project and some of the tips and tricks I’ve learned along the way. How does your team user composer-packages? Do you have a favorite setting that I didn’t mention? Feel free to drop a comment and share what works for you and your team.

Categories: FLOSS Project Planets

FSF Blogs: May 2019: Photos from Aalborg and Copenhagen

GNU Planet! - Thu, 2019-08-08 11:35

Free Software Foundation president Richard Stallman (RMS) was in Denmark in May 2019.

After a visit to the beach in nearby Slettestrand the day before, RMS went to Aalborg, where he delivered his speech “Free software and your freedom”1 at Aalborg University (AAU), on May 6th.

Photos courtesy of Aalborg University (copyright © 2019, CC BY 4.0).

The next day, he went on to Odense, where he gave his speech “The danger of mass surveillance” at Syddansk Universitet (the University of Southern Denmark, or SDU). Next, he headed on to Copenhagen, where he gave the following three speeches.

On May 8th, he was at the IT-Universitetet i København (IT University of Copenhagen, or ITU) to give his speech “Free Software and your freedom in computing,” to an audience of about three hundred people.

Photos courtesy of ITU Innovators (copyright © 2019, CC BY 4.0).

On May 9th, he was in the Lundbeckfond Auditorium of the Copenhagen Biocenter, at Københavns Universitet (University of Copenhagen, or KU), to give his speech “Computing, freedom, and privacy.”

Photos courtesy of the University of Copenhagen (copyright © 2019, CC BY 4.0).

On May 10th, he gave his speech "Should we have more surveillance than the USSR?" at Danmarks Tekniske Universitet (the Technical University of Denmark, or DTU).

On the day after that, while still in Copenhagen, he visited the Danish-French School, the only school in Denmark to use free software exclusively.

Thank you to everyone who made this trip possible!

Please fill out our contact form, so that we can inform you about future events in and around Aalborg, Odense, Copenhagen.

Please see www.fsf.org/events for a full list of all of RMS's confirmed engagements,
and contact rms-assist@gnu.org if you'd like him to come speak.

1. The recording will soon be posted on our audio-video archive.
Categories: FLOSS Project Planets

May 2019: Photos from Aalborg and Copenhagen

FSF Blogs - Thu, 2019-08-08 11:35

Free Software Foundation president Richard Stallman (RMS) was in Denmark in May 2019.

After a visit to the beach in nearby Slettestrand the day before, RMS went to Aalborg, where he delivered his speech “Free software and your freedom”1 at Aalborg University (AAU), on May 6th.

Photos courtesy of Aalborg University (copyright © 2019, CC BY 4.0).

The next day, he went on to Odense, where he gave his speech “The danger of mass surveillance” at Syddansk Universitet (the University of Southern Denmark, or SDU). Next, he headed on to Copenhagen, where he gave the following three speeches.

On May 8th, he was at the IT-Universitetet i København (IT University of Copenhagen, or ITU) to give his speech “Free Software and your freedom in computing,” to an audience of about three hundred people.

Photos courtesy of ITU Innovators (copyright © 2019, CC BY 4.0).

On May 9th, he was in the Lundbeckfond Auditorium of the Copenhagen Biocenter, at Københavns Universitet (University of Copenhagen, or KU), to give his speech “Computing, freedom, and privacy.”

Photos courtesy of the University of Copenhagen (copyright © 2019, CC BY 4.0).

On May 10th, he gave his speech "Should we have more surveillance than the USSR?" at Danmarks Tekniske Universitet (the Technical University of Denmark, or DTU).

On the day after that, while still in Copenhagen, he visited the Danish-French School, the only school in Denmark to use free software exclusively.

Thank you to everyone who made this trip possible!

Please fill out our contact form, so that we can inform you about future events in and around Aalborg, Odense, Copenhagen.

Please see www.fsf.org/events for a full list of all of RMS's confirmed engagements,
and contact rms-assist@gnu.org if you'd like him to come speak.

1. The recording will soon be posted on our audio-video archive.
Categories: FLOSS Project Planets

Stack Abuse: Rounding Numbers in Python

Planet Python - Thu, 2019-08-08 10:10

Using a computer in order to do rather complex Math is one of the reasons this machine was originally developed. As long as integer numbers and additions, subtractions, and multiplications are exclusively involved in the calculations, everything is fine. As soon as floating point numbers or fractions, as well as divisions, come into play it enormously complicates the whole matter.

As a regular user, we are not fully aware of these issues that happen behind the scenes and may end up with rather surprising, and possibly inaccurate results for our calculations. As developers, we have to ensure that appropriate measures are taken into account in order to instruct the computer to work in the right way.

In our daily life we use the decimal system that is based on the number 10. The computer uses the binary system, which is base 2, and internally it stores and processes the values as a sequence of 1s and 0s. The values we work with have to be constantly transformed between the two representations. As explained in Python's documentation:

...most decimal fractions cannot be represented exactly as binary fractions. A consequence is that, in general, the decimal floating-point numbers you enter are only approximated by the binary floating-point numbers actually stored in the machine.

This behavior leads to surprising results in simple additions, as shown here:

Listing 1: Inaccuracies with floating point numbers

>>> s = 0.3 + 0.3 + 0.3 >>> s 0.8999999999999999

As you can see here, the output is inaccurate, as it should result to 0.9.

Listing 2 shows a similar case for formatting a floating point number for 17 decimal places.

Listing 2: Formatting a floating point number

>>> format(0.1, '.17f') '0.10000000000000001'

As you may have learned from the examples above, dealing with floating point numbers is a bit tricky, and requires additional measures in order to achieve the correct result, and to minimize computing errors. Rounding the value can solve at least some of the problems. One possibility is the built-in round() function (for more details regarding its usage see below):

Listing 3: Calculating with rounded values

>>> s = 0.3 + 0.3 + 0.3 >>> s 0.8999999999999999 >>> s == 0.9 False >>> round(0.9, 1) == 0.9 True

As an alternative, you can work with the math module, or explicitly work with fractions stored as two values (numerator and denominator) instead of the rounded, rather inexact floating point values.

In order to store the values like that the two Python modules decimal and fraction come into play (see examples below). But first, let us have a closer look at the term "rounding".

What is Rounding?

In a few words, the process of rounding means:

...replacing [a value] with a different number that is approximately equal to the original, but has a shorter, simpler, or more explicit representation.

Source: https://en.wikipedia.org/wiki/Rounding

Basically, it adds inaccuracy to a precisely calculated value by shortening it. In most cases this is done by removing digits after the decimal point, for example from 3.73 to 3.7, 16.67 to 16.7, or 999.95 to 1000.

Such a reduction is done for several reasons - for example, saving space when storing the value, or simply for removing unused digits. Furthermore, output devices such as analogue displays or clocks can show the computed value with only a limited precision, and require adjusted input data.

In general, two rather simple rules are applied for rounding, you may remember them from school. The digits 0 to 4 lead to rounding down, and the numbers 5 to 9 lead to rounding up. The table below shows a selection of use cases.

| original value | rounded to | result | |----------------|--------------|--------| | 226 | the ten | 230 | | 226 | the hundred | 200 | | 274 | the hundred | 300 | | 946 | the thousand | 1,000 | | 1,024 | the thousand | 1,000 | | 10h45m50s | the minute | 10h45m | Rounding Methods

Mathematicians have developed a variety of different rounding methods in order to address the problem of rounding. This includes simple truncation, rounding up, rounding down, rounding half-up, rounding half-down, as well as rounding half away from zero and rounding half to even.

As an example, rounding half away from zero is applied by the European Commission on Economical and Financial Affairs when converting currencies to the Euro. Several countries, such as Sweden, The Netherlands, New Zealand, and South Africa follow the rule named "cash rounding", "penny rounding", or "Swedish rounding".

[Cash rounding] occurs when the minimum unit of account is smaller than the lowest physical denomination of currency. The amount payable for a cash transaction is rounded to the nearest multiple of the minimum currency unit available, whereas transactions paid in other ways are not rounded.

Source: https://en.wikipedia.org/wiki/Cash_rounding

In South Africa, since 2002 cash rounding is done to the nearest 5 cents. In general, this kind of rounding does not apply to electronic non-cash payments.

In contrast, rounding half to even is the default strategy for Python, Numpy, and Pandas, and is in use by the built-in round() function that was already mentioned before. It belongs to the category of the round-to-nearest methods, and is also known as convergent rounding, statistician's rounding, Dutch rounding, Gaussian rounding, odd–even rounding, and bankers' rounding. This method is defined in IEEE 754 and works in such a way, that "if the fractional part of x is 0.5, then y is the even integer nearest to x." It is assumed "that the probabilities of a tie in a dataset being rounded down or rounded up are equal" which is usually the case, in practice. Although not fully perfect this strategy leads to appreciable results.

The table below gives practical rounding examples for this method:

| original value | rounded to | |----------------|------------| | 23.3 | 23 | | 23.5 | 24 | | 24.0 | 24 | | 24.5 | 24 | | 24.8 | 25 | | 25.5 | 26 | Python Functions

Python comes with the built-in function round() that is quite useful in our case. It accepts two parameters - the original value, and the number of digits after the decimal point. The listing below illustrates the usage of the method for one, two, and four digits after the decimal point.

Listing 4: Rounding with a specified number of digits

>>> round(15.45625, 1) 15.5 >>> round(15.45625, 2) 15.46 >>> round(15.45625, 4) 15.4563

If you call this function without the second parameter the value is rounded to a full integer value.

Listing 5: Rounding without a specified number of digits

>>> round(0.85) 1 >>> round(0.25) 0 >>> round(1.5) 2

Rounded values work fine in case you do not require absolutely precise results. Be aware of the fact that comparing rounded values can also be a nightmare. It will become more obvious in the following example - the comparison of rounded values based on pre-rounding, and post-rounding.

The first calculation of Listing 6 contains pre-rounded values, and describes rounding before adding the values up. The second calculation contains a post-rounded summary which means rounding after the summation. You will notice that the outcome of the comparison is different.

Listing 6: Pre-rounding vs. post-rounding

>>> round(0.3, 10) + round(0.3, 10) + round(0.3, 10) == round(0.9, 10) False >>> round(0.3 + 0.3 + 0.3, 10) == round(0.9, 10) True Python Modules for Floating Point Calculations

There are four popular modules that can help you properly deal with floating point numbers. This includes the math module, the Numpy module, the decimal module, and the fractions module.

The math module is centered around mathematical constants, floating point operations, and trigonometric methods. The Numpy module describes itself as "the fundamental package for scientific computing", and is famous for its variety of array methods. The decimal module covers decimal fixed point and floating point arithmetic, and the fractions module deals with rational numbers, specifically.

First, we have to try to improve the calculation from Listing 1. As Listing 7 shows, after having imported the math module we can access the method fsum() that accepts a list of floating point numbers. For the first calculation there is no difference between the built-in sum() method, and the fsum() method from the math module, but for the second one it is, and returns the correct result we would expect. The precision depends on the underlying IEEE 754 algorithm.

Listing 7: Floating-point calculations with the help of the math module

>>> import math >>> sum([0.1, 0.1, 0.1]) 0.30000000000000004 >>> math.fsum([0.1, 0.1, 0.1]) 0.30000000000000004 >>> sum([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]) 0.9999999999999999 >>> math.fsum([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]) 1.0

Second, let us have a look at the Numpy module. It comes with the around() method that rounds the values provided as an array. It processes the single values in the same way as the default round() method.

In order to compare values Numpy offers the equal() method. Similar to around() it accepts single values as well as lists of values (so-called vectors) to be processed. Listing 8 shows a comparison for single values as well as rounded values. The observed behavior is quite similar to the previously shown methods.

Listing 8: Comparing values using the equal method from the Numpy module

>>> import numpy >>> print (numpy.equal(0.3, 0.3)) True >>> print (numpy.equal(0.3 + 0.3 + 0.3 , 0.9)) False >>> print (numpy.equal(round(0.3 + 0.3 + 0.3) , round(0.9))) True

Option three is the decimal module. It offers exact decimal representation, and preserves the significant digits. The default precision is 28 digits, and you can change this value to a number that is as large as needed for your problem. Listing 9 shows how to use a precision of 8 digits.

Listing 9: Creating decimal numbers using the decimal module

>>> import decimal >>> decimal.getcontext().prec = 8 >>> a = decimal.Decimal(1) >>> b = decimal.Decimal(7) >>> a / b Decimal('0.14285714')

Now, comparing of float values becomes a lot easier, and leads to the result we were looking for.

Listing 10: Comparisons using the decimal module

>>> import decimal >>> decimal.getcontext().prec = 1 >>> a = decimal.Decimal(0.3) >>> b = decimal.Decimal(0.3) >>> c = decimal.Decimal(0.3) >>> a + b + c Decimal('0.9') >>> a + b + c == decimal.Decimal('0.9') True

The decimal module also comes with a method to round values - quantize(). The default rounding strategy is set to rounding half to even, and can also be changed to a different method if needed. Listing 11 illustrates the usage of the quantize() method. Please note that the number of digits is specified using a decimal value as a parameter.

Listing 11: Rounding a value using quantize()

>>> d = decimal.Decimal(4.6187) >>> d.quantize(decimal.Decimal("1.00")) Decimal('4.62')

Last but not least, we will have a look at the fractions module. This module allows you to handle floating point values as fractions, for example 0.3 as 3/10. This simplifies the comparison of floating point values, and completely eliminates rounding of values. Listing 12 shows how to use the fractions module.

Listing 12: Storing and comparing floating point values as fractions

>>> import fractions >>> fractions.Fraction(4, 10) Fraction(2, 5) >>> fractions.Fraction(6, 18) Fraction(1, 3) >>> fractions.Fraction(125) Fraction(125, 1) >>> a = fractions.Fraction(6, 18) >>> b = fractions.Fraction(1, 3) >>> a == b True

Furthermore, the two modules decimal and fractions can be combined, as shown in the next example.

Listing 13: Working with decimals and fractions

>>> import fractions >>> import decimal >>> a = fractions.Fraction(1,10) >>> b = fractions.Fraction(decimal.Decimal(0.1)) >>> a,b (Fraction(1, 10), Fraction(3602879701896397, 36028797018963968)) >>> a == b False Conclusion

Storing and processing floating point values correctly is a bit of a mission, and requires a lot of attention for programmers. Rounding the values may help, but be sure to check the correct order of rounding, and the method that you use. This is most important when developing things like financial software, so you'll want to check the rules of local law for rounding.

Python gives you all the tools that are needed, and comes with "batteries included". Happy hacking!

Acknowledgements

The author would like to thank Zoleka Hofmann for her critical comments while preparing this article.

Categories: FLOSS Project Planets

Google Code-in 2018 trip report

Planet KDE - Thu, 2019-08-08 10:09

Hello! In June, I had the opportunity to be the mentor representing KDE in the Google Code-in (GCi) 2018 trip in San Francisco, California. For those who don't know what GCi is, it is basically a competition organized by Google for students with ages between 13-17 years old that introduces them into open source contributions … Continue reading Google Code-in 2018 trip report

Categories: FLOSS Project Planets

wishdesk.com: Why build a local business website on Drupal 8

Planet Drupal - Thu, 2019-08-08 09:30
If you have a local business, you will benefit immensely from a strong online presence. In this post, we will discuss why Drupal 8 is a great choice to build a local website.
Categories: FLOSS Project Planets

Specbee: Setup Responsive Images in Drupal 8 - A Step-by-Step Guide

Planet Drupal - Thu, 2019-08-08 08:11
Setup Responsive Images in Drupal 8 - A Step-by-Step Guide Akshay Devadiga 08 Aug, 2019 Top 10 best practices for designing a perfect UX for your mobile app

Back in early 2010, when Jason Grigsby pointed out that simply setting a percentage width on images was not enough, and that you needed to resize these images as well for a better user experience. He pointed out that if you served the right sized images on the original responsive demo site, more than 75% of the weight of those images can be shaved on smaller screens. 

Ever since, the debate on responsive images have evolved in what is the best solution to render the perfect, responsive images without any hassle.

We all know how Drupal 7 does a great job in handling responsive images with its modules. However, with Drupal 8, things are even better now!

Responsive Images in Drupal 8

The Responsive Image module in Drupal 8 provides an image formatter that maps the breakpoint of the original image to render a flawless responsive image using a picture tag.

When we observe how Drupal 8 handles responsive images when compared to Drupal 7, some of the features to be noted are:

Drupal 7 consists of the contributed module picture element, which in the latest version is known as Responsive Images.
In addition to this, Responsive images & Breakpoint modules are a part of the Drupal core in the latest version of the CMS.

The Problem

One of the major problems with the images in web development is, browsers do not know about the images, and are clueless about what sized images are rendering in relation with a viewport of different screens until the CSS & Javascripts are loaded.

However, the browser can know about the environment in which the images are rendering, which includes the size of the viewport and resolution of the screen.

The Solution 

As we mentioned in previous sections, responsive images use picture element which basically has sizes and srcset attributes which play a major role in notifying the browser to choose the best images based on the image style selections.  

So Drupal 8 has done a great job in providing the responsive images module in the core. This will download the lower sized images for the devices with lower screen resolution, resulting in better website load time and improved performance. 

Steps to reproduce
  1. Enable Responsive images and breakpoint module.
  2. Setup the breakpoints for your projects theme.
  3. Setting up the image styles for responsive images
  4. Creating a responsive image style for your theme
  5. Assigning the responsive image style to an image field.
Enable Responsive images and breakpoint module

Since it's a part of drupal 8 core, we will not require any other extra module. All you have to do is enable the responsive images module, since the breakpoint module will be installed with the standard profile. Else enable the breakpoint module.

To enable the module goto->admin->extends select the module and enable the module.

Setup the breakpoints for your project's theme
 

Setting up the theme’s breakpoint is the most important part for the responsiveness of your site.


If you are using a core theme like bartik , seven, umami or claro, you will already have the breakpoints file and you don’t have to create any new ones. 

However, if you are using a custom theme for your project, it is important that you define the breakpoints in "yourthemename.breakpoints.yml" which can be found in your theme directory, usually found in "/themes/custom/yourthemename".

Each breakpoint will assign the images to media query.  For example images which are rendering in mobile might be smaller i.e width less than 768px, where in medium screens will have a width between 768px to 1024px.


Each breakpoint will have: 

label:  Is the valid label given for the breakpoint.
mediaQuery:  Is the viewport within which the images are rendered.
weight:  For the order of display.
multipliers:  It's a measure of the viewport's device resolution normally 1x will be used for standard sizes and 2x for retina display.

Setting up the image styles for responsive images

Now we will have to create an image style for each of the breakpoints. You can configure your own Drupal 8 image styles at admin->config->media->image-styles

Click ‘Add image style’.  Give the valid name for your image style & use scale and crop effect which will provide the cropped images. If the images are stretched, add multiple image style for different viewports.

Creating a responsive image style for your theme 

This is where you provide the multiple image style options to the browser and let the browser choose the best out of the lot. 


To create new responsive Drupal 8  image style navigate to:
Home -> admin- > config-> media->responsive-image-style and click on ‘Add responsive image’. 

Give a valid name for your responsive image style & select the breakpoint group (choose your theme) & assign the image styles to the breakpoints listed 

There are multiple options for the image style configurations

  • Choose single image style: Where you can select the single image style that will be rendered on the particular screen
  • Choose multiple image style: Where you can select the multiple-image style and also specify the viewport width for the image style

At last, there is an option to select a fallback image style. The fallback image style should only appear on the site if an error occurs.

Assigning the responsive image style to an image field 
  • Once all the configurations are done, move to the image field by adding the responsive image style.
  • To do that go to the field’s manage display and select the responsive image style which we created.
  • Add content and see the results on the page with a responsive image style.

     

Final Results 

 The image at a minimum width of 1024px (For large Devices).

Image at minimum width of 768px (For Medium Devices).

Image at maximum width 767px (For Small Devices).

Drupal Planet Shefali ShettyApr 05, 2017 Subscribe For Our Newsletter And Stay Updated Subscribe Shefali ShettyApr 05, 2017 Recent Posts Image Setup Responsive Images in Drupal 8 - A Step-by-Step Guide Image Top 15 Drupal Distributions for Accelerating Your Web Development Process Image Headless Drupal – Why Top Enterprises Are Choosing Decoupled Drupal Websites? Explore Our Drupal Services TAKE ME THERE Featured Success Stories

Know more about our technology driven approach to recreate the content management workflow for [24]7.ai

link

Find out how we transformed the digital image of world’s largest healthcare provider, an attribute that defined their global presence in the medical world.

link

Develop an internal portal aimed at encouraging sellers at Flipkart to obtain latest insights with respect to a particular domain.

link
Categories: FLOSS Project Planets

"Menno's Musings": Python virtualenvs talk

Planet Python - Thu, 2019-08-08 07:33

I had the pleasure of giving a talk about Python virtual environments at this week's Christchurch Python meetup. It described the problem that virtualenvs solve, some gotchas and the tools people use to create and manage them. We also spent some time on some of the newer entrants in this space including pew, pipenv and poetry. The slides are available.

Read more… (1 min remaining to read)

Categories: FLOSS Project Planets

Catalin George Festila: Python 3.7.3 : Using the flask - part 012.

Planet Python - Thu, 2019-08-08 07:21
The goal of this tutorial step is to understand how the project can use the new features and implementation of the project. Because in the last tutorial I used the flask_mail python module, now I will add into my project structure. One good issue is registration issue for users. First, you need to see the full project and changes at my GitHub project. I used the itsdangerous python module to use
Categories: FLOSS Project Planets

Srijan Technologies: Your Step-by-Step Drupal Migration Guide

Planet Drupal - Thu, 2019-08-08 06:14

With Dries’ latest announcement on the launch of Drupal 9 in 2020, enterprises are in an urgent need to upgrade from Drupal 7 and 8 to version 9.

Categories: FLOSS Project Planets

Agiledrop.com Blog: Interview with Ricardo Amaro: The future is open, the future is community and inclusion

Planet Drupal - Thu, 2019-08-08 04:54

In our latest interview, Ricardo Amaro of Acquia reveals how his discovery of Drupal has enabled him to work on projects he enjoys and that make a meaningful impact. Give it a read to learn more about his contributions and what the Drupal community in Portugal is like.

READ MORE
Categories: FLOSS Project Planets

Moshe Zadka: Designing Interfaces

Planet Python - Thu, 2019-08-08 01:20

One of the items of feedback I got from the article about interface immutability is that it did not give any concrete feedback for how to design interfaces. Given that they are forever, it would be good to have some sort of guidance.

The first item is that you want something that uses the implementation, as well as several distinct implementations. However, this item is too obvious: in almost all cases I have seen in the wild of a bad interface, this guideline was followed.

It was also followed in all cases of a good interface.

I think this guideline is covered well enough that by the time anyone designs a real interface, they understand that. Why am I mentioning this guideline at all, then?

Because I think it is important for the context of the guideline that I do think actually distinguishes good interfaces from bad interfaces. It is almost identical to the non-criterion above!

The real guideline is: something that uses the implementation, as well as several distinct implementations that do not share a superclass (other than object or whatever is in the top of the hierarchy).

This simple addition, preventing the implementations from sharing a superclass, is surprisingly powerful. It means each implementation has to implement the "boring" parts by hand. This will immediately cause pressure to avoid "boring" parts, and instead put them in a wrapper, or in the interface user.

Otherwise, the most common failure mode is that the implementations are all basic variants on what is mostly the "big superclass".

In my experience, just the constraint on not having a "helper superclass" puts appropriate pressure on interfaces to be good.

(Thanks to Tom Most for his encouragement to write this, and the feedback on an earlier draft. Any mistakes that remain are my responsibility.)

Categories: FLOSS Project Planets

Agaric Collective: Migrating files and images into Drupal

Planet Drupal - Wed, 2019-08-07 22:37

We have already covered two of many ways to migrate images into Drupal. One example allows you to set the image subfields manually. The other example uses a process plugin that accomplishes the same result using plugin configuration options. Although valid ways to migrate images, these approaches have an important limitation. The files and images are not removed from the system upon rollback. In the previous blog post, we talked further about this topic. Today, we are going to perform an image migration that will clear after itself when it is rolled back. Note that in Drupal images are a special case of files. Even though the example will migrate images, the same approach can be used to import any type of file. This migration will also serve as the basis for explaining migration dependencies in the next blog post.

File entity migrate destination

All the examples so far have been about creating nodes. The migrate API is a full ETL framework able to write to different destinations. In the case of Drupal, the target can be other content entities like files, users, taxonomy terms, comments, etc. Writing to content entities is straightforward. For example, to migrate into files, the process section is configured like this:

destination: plugin: 'entity:file'

You use a plugin whose name is entity: followed by the machine name of your target entity. In this case file. Other possible values are user, taxonomy_term, and comment. Remember that each migration definition file can only write to one destination.

Source section definition

The source of a migration is independent of its destination. The following code snippet shows the source definition for the image migration example:

source: constants: SOURCE_DOMAIN: 'https://agaric.coop' DRUPAL_FILE_DIRECTORY: 'public://portrait/' plugin: embedded_data data_rows: - photo_id: 'P01' photo_url: 'sites/default/files/2018-12/micky-cropped.jpg' - photo_id: 'P02' photo_url: '' - photo_id: 'P03' photo_url: 'sites/default/files/pictures/picture-94-1480090110.jpg' - photo_id: 'P04' photo_url: 'sites/default/files/2019-01/clayton-profile-medium.jpeg' ids: photo_id: type: string

Note that the source contains relative paths to the images. Eventually, we will need an absolute path to them. Therefore, the SOURCE_DOMAIN constant is created to assemble the absolute path in the process pipeline. Also, note that one of the rows contains an empty photo_url. No file can be created without a proper URL. In the process section we will accommodate for this. An alternative could be to filter out invalid data in a source clean up operation before executing the migration.

Another important thing to note is that the row identifier photo_id is of type string. You need to explicitly tell the system the name and type of the identifiers you want to use. The configuration for this varies slightly from one source plugin to another. For the embedded_data plugin, you do it using the ids configuration key. It is possible to have more than one source column as identifier. For example, if the combination of two columns (e.g. name and date of birth) are required to uniquely identify each element (e.g. person) in the source.

You can get the full code example at https://github.com/dinarcon/ud_migrations The module to enable is UD migration dependencies introduction whose machine name is ud_migrations_dependencies_intro. The migration to run is udm_dependencies_intro_image. Refer to this article to learn where the module should be placed.

Process section definition

The fields to map in the process section will depend on the target. For files and images, only one entity property is required: uri. Its value should be set to the file path within Drupal using stream wrappers. In this example, the public stream (public://) is used to store the images in a location that is publicly accessible by any visitor to the site. If the file was already in the system and we knew the path the whole process section for this migration could be reduced to two lines:

process: uri: source_column_file_uri

That is rarely the case though. Fortunately, there are many process plugins that allow you to transform the available data. When combined with constants and pseudofields, you can come up with creative solutions to produce the format expected by your destination.

Skipping invalid records

The source for this migration contains one record that lacks the URL to the photo. No image can be imported without a valid path. Let’s accommodate for this. In the same step, a pseudofield will be created to extract the name of the file out of its path.

psf_destination_filename: - plugin: callback callable: basename source: photo_url - plugin: skip_on_empty method: row message: 'Cannot import empty image filename.'

The psf_destination_filename pseudofield uses the callback plugin to derive the filename from the relative path to the image. This is accomplished using the basename PHP function. Also, taking advantage of plugin chaining, the system is instructed to skip process the row if no filename could be obtained. For example, because an empty source value was provided. This is done by the skip_on_empty which is also configured log a message to indicate what happened. In this case, the message is hardcoded. You can make it dynamic to include the ID of the row that was skipped using other process plugins. This is left as an exercise to the curious reader. Feel free to share your answer in the comments below.

Tip: To read the messages log during any migration, execute the following Drush command: drush migrate:messages [migration-id].

Creating the destination URI

The next step is to create the location where the file is going to be saved in the system. For this, the psf_destination_full_path pseudofield is used to concatenate the value of a constant defined in the source and the file named obtained in the previous step. As explained before, order is important when using pseudofields as part of the migrate process pipeline. The following snippet shows how to do it:

psf_destination_full_path: - plugin: concat source: - constants/DRUPAL_FILE_DIRECTORY - '@psf_destination_filename' - plugin: urlencode

The end result of this operation would be something like public://portrait/micky-cropped.jpg. The URI specifies that the image should be stored inside a portrait subdirectory inside Drupal’s public file system. Copying files to specific subdirectories is not required, but it helps with file organizations. Also, some hosting providers might impose limitations on the number of files per directory. Specifying subdirectories for your file migrations is a recommended practice.

Also note that after the URI is created, it gets encoded using the urlencode plugin. This will replace special characters to an equivalent string literal. For example, é and ç will be converted to %C3%A9 and %C3%A7 respectively. Space characters will be changed to %20. The end result is an equivalent URI that can be used inside Drupal, as part of an email, or via another medium. Always encode any URI when working with Drupal migrations.

Creating the source URI

The next step is to create assemble an absolute path for the source image. For this, you concatenate the domain stored in a source constant and the image relative path stored in a source column. The following snippet shows how to do it:

psf_source_image_path: - plugin: concat delimiter: '/' source: - constants/SOURCE_DOMAIN - photo_url - plugin: urlencode

The end result of this operation will be something like https://agaric.coop/sites/default/files/2018-12/micky-cropped.jpg. Note that the concat and urlencode plugins are used just like in the previous step. A subtle difference is that a delimiter is specifying in the concatenation step. This is because, contrary to the DRUPAL_FILE_DIRECTORY constant, the SOURCE_DOMAIN constant does not end with a slash (/). This was done intentionally to highlight two things. First, it is important to understand your source data. Second, you can transform it as needed by using various process plugins.

Copying the image file to Drupal

Only two tasks remain to complete this image migration: download the image and assign the uri property of the file entity. Luckily, both steps can be accomplished at the same time using the file_copy plugin. The following snippet shows how to do it:

uri: plugin: file_copy source: - '@psf_source_image_path' - '@psf_destination_full_path' file_exists: 'rename' move: FALSE

The source configuration of file_copy plugin expects an array of two values: the URI to copy the file from and the URI to copy the file to. Optionally, you can specify what happens if a file with the same name exists in the destination directory. In this case, we are instructing the system to rename the file to prevent name clashes. The way this is done is appending the string _X to the filename and before the file extension. The X is a number starting with zero (0) that keeps incrementing until the filename is unique. The move flag is also optional. If set to TRUE it tells the system that the file should be moved instead of copied. As you can guess, Drupal does not have access to the file system in the remote server. The configuration option is shown for completeness, but does not have any effect in this example.

In addition to downloading the image and place it inside Drupal’s file system, the file_copy also returns the destination URI. That is why this plugin can be used to assign the uri destination property. And that’s it, you have successfully imported images into Drupal! Clever use of the process pipeline, isn’t it? ;-)

One important thing to note is an image’s alternative text, title, width, and height are not associated with the file entity. That information is actually stored in a field of type image. This will be illustrated in the next article. To reiterate, the same approach to migrate images can be used to migrate any file type.

Technical note: The file entity contains other properties you can write to. For a list of available options check the baseFieldDefinitions() method of the File class defining the entity. Note that more properties can be available up in the class hierarchy. Also, this entity does not have multiple bundles like the node entity does.

What did you learn in today’s blog post? Had you created file migrations before? If so, had you followed a different approach? Did you know that you can do complex data transformations using process plugins? Did you know you can skip the processing of a row if the required data is not available? Please share your answers in the comments. Also, I would be grateful if you shared this blog post with your colleagues.

This blog post series, cross-posted at UnderstandDrupal.com as well as here on Agaric.coop, is made possible thanks to these generous sponsors. Contact Understand Drupal if your organization would like to support this documentation project, whether the migration series or other topics.

 

Read more and discuss at agaric.coop.

Categories: FLOSS Project Planets

Drupal Association blog: Because...Drupal!

Planet Drupal - Wed, 2019-08-07 19:15

Today is the start of our membership campaign which runs through August 31. This month, we've asked members to share why they are part of the Association. We hope you find some inspiration from your fellow community and that you'll join and share:

Join membership

Share the campaign


"I believe in Drupal's future and I love the opportunity that Drupal provides to people around the world." ~ Jiang Zhan


"The Drupal Association helps to support the Drupal community.

The Drupal community is the reason most folks start using Drupal and never leave.
Attend a local Drupal camp, meetup, or contribution day to experience how welcoming + helpful the community is." ~ Leslie Glynn


"I love developing for…
Working with…
Problem solving with…
Enhancing…
Drupal!" ~ Wil Roboly


"I support the people, time, and commitments made by those who build and grow Drupal." ~ Erica Reed


"I believe in socially sustainable ecosystems and Drupal is just that. It's very powerful to have local communities supporting Drupal, with the Drupal Association empowering global communication and a unified message. This must endure!" ~ Imre Gmelig Meijling


"I feel this will help others the way Drupal has helped me pursue my career and open up possibilities of learning and exploring.

This is another way of giving back to Drupal." Jaideep Singh Kandari

Help grow our membership by joining to support the global Drupal Association or by sharing this campaign. We're here because we love Drupal and the opportunities that come from being part of this open source project. Thanks for being here and for all that you contribute!

Categories: FLOSS Project Planets

PyPy Development: A second life for the Sandbox

Planet Python - Wed, 2019-08-07 15:31
Hi all,

Anvil is a UK-based company sponsoring one month of work to revive PyPy's "sandbox" mode and upgrade it to PyPy3. Thanks to them, sandboxing will be given a second life!

The sandboxed PyPy is a special version of PyPy that runs fully isolated. It gives a safe way to execute arbitrary Python programs (whole programs, not small bits of code inside your larger Python program). Such scripts can be fully untrusted, and they can try to do anything—there are no syntax-based restrictions, for example—but whatever they do, any communication with the external world is not actually done but delegated to the parent process. This is similar but much more flexible than Linux's Seccomp approach, and it is more lightweight than setting up a full virtual machine. It also works without operating system support.

However, during the course of the years the sandbox mode of PyPy has been mostly unmaintained and unsupported by the core developers, mostly because of a lack of interest by users and because it took too much effort to maintain it.

Now we have found that we have an actual user, Anvil. As far as I can tell they are still using a very old version of PyPy, the last one that supported sandboxing. This is where this contract comes from: the goal is to modernize sandboxing and port it to PyPy3.

Part of my motivation for accepting this work is that I may have found a way to tweak the protocol on the pipe between the sandboxed PyPy and the parent controller process. This should make the sandboxed PyPy more resilient against future developments and easier to maintain; at most, in the future some tweaks will be needed in the controller process but hopefully not deep inside the guts of the sandboxed PyPy. Among the advantages, such a more robust solution should mean that we can actually get a working sandboxed PyPy—or sandboxed PyPy3 or sandboxed version of any other interpreter written in RPython—with just an extra argument when calling rpython to translate this interpreter. If everything works as planned, sandboxing may be given a second life.

Armin Rigo
Categories: FLOSS Project Planets

Kate - Initial Rust LSP support landed!

Planet KDE - Wed, 2019-08-07 15:02

Initial support for the rls Rust LSP server has landed in kate.git master. The matching rls issue about this can be found here.

Given I am no Rust expert, I can only verify that at least some operations seem to work for me if the Rust toolchain is setup correctly ;=)

The current experience isn’t that nice as with clangd, for example I get no symbols outline here. What is possible with clangd can be seen in one of my previous posts, video included.

Any help to improve this is welcome. The patch that landed can be viewed here, lend a hand if you know how to fix up stuff!

Categories: FLOSS Project Planets

Pages