FLOSS Project Planets

Improving the remote experience: treadmill

Planet KDE - Thu, 2021-04-15 15:57

Last year I decided to add an improvement to my home office, a treadmill. I thought about during the total lock-down we suffered in Spain in spring 2020. The reason for not trying it earlier was that I was skeptical about keeping my productivity level while walking on the treadmill. Finally I made the decision to try out and asked for one to The Three Wise Men. They were kind enough to bring it.

After a few weeks using it, I would like to report about it since several of my colleagues at MBition/Daimler asked me about it. I hope that reading about my experience is useful to you.

Select the right treadmill

I started by doing some research on which treadmill to buy. The main characteristics that led my decision were:

  • Walking vs running: I wanted a treadmill for walking, not for running. There are quite a few models that has 6 to 7 km/h as speed limit and no support or add-ons to hold on to while walking. The intention is to avoid any clashing with my standing desk converter.
  • I am a big man so I need a big treadmill: the market offers treadmills with different length, surface and weight limits. I searched for one that can afford a big man like me and that was as wide as as possible. Falling from it was a concern.
  • Remote control: since you will be walking while working, you need a way to control the treadmill remotely, either with a remote control, an app or similar. I selected one with a remote control.
  • With wheels: I need to move the treadmill often since I alternate using the treadmill with working standing up or seated. I wanted one with wheels so it is easier to move. Treadmills are heavy.
  • Limited investment: my idea was to try out first so I did not want to invest a lot. If it works, I will invest more in a replacement when needed.
  • Pay attention to the noise level: my treadmill is noisy although not enough to be annoying or to be heard by others while in video calls. Check the specifications, I did not so I simply was a little lucky..

I bought this model, produced by 2WD, ASIN/model B08GLTX8LK, through Amazon for €299. I had no issues with the purchase.

Usage

I use the treadmill between 3 to 4 hours a day. I started using it between 5 and 6 hours but soon I got hurt in one foot which forced me to stop for some time. First lesson learnt, take it easy, specially if, like myself, you are not in great shape.

At first I ended up so tired that it was hard for me to keep good levels of concentration during the last part of any working day. As I got more used to using the treadmill, I felt more energetic in general so that tiredness is little by little going away. My productivity is increasing overtime compared to the first few days. The last few weeks I even have energy left to do some soft exercise after work.

I started walking at 2 km/h. I increased to 2.5 km/h after 2 weeks. A few weeks later I tried 3 km/h but it was harder for me to concentrate, it is too fast for now. There is a mismatch by the way between the speed and the distance walked marked by the treadmill. I think that the average speed I walk is a little below 2.5 km/h. In am current walking between 3 and 4 hours a day which is around 7-8.5 kms (10k steps is around 8 kms). In any case, I try to reach the 6.5 kms mark every day. I am accomplishing it regularly during the last few weeks.

Can I work normally while walking?

This is the question most colleagues ask me. The answer is yes… for most activities.

My experience is that I can work normally while walking, keeping good productivity levels, while performing most type of activities, specially during most meetings.

In which ones I have seen a reduction of productivity?

I detected a productivity decrease in those activities which require high levels of concentration or creativity like complex meetings with many people that I facilitate, those times when I need to come up with new ideas, analysis of complex data, etc. The good news is that I did detect this productivity reduction early. The longer I have been using the treadmill though, the more type tasks I can do without noticing a productivity reduction. So I plan to try again during the coming weeks some of those activities that I dropped early on.

Walking is helping me a lot to go through those days with back to back meetings. I pay better attention and get less bored compared to standing up. As I get more used to walking, my energy levels during the afternoons are increasing, as mentioned, which helps me to get through the last couple of hours during long working days. It was not like that at first though, so plan accordingly.

The unexpected surprises

The treadmill uses IR to connect to the remote control which interferes with an IR based device I had at my office, the HDMI hub. I use two laptops and two monitors and used the HDMI hub to have one of the two screens assigned to one of the laptops while the default config is to have both monitors assigned to my working laptop. I did not find a way to prevent such interference so I had to remove the HDMI hub. I am looking for alternatives although the impact in my daily workflow is low. The problems were easy to detect because every time I turned the treadmill on, one of my screens turned off although both laptops detected it.. So the takeaway is: watch out for IR interference.

I trickier surprise for which I have not find a solution is the problems associated with the PLC. I have my office connected to the living room, where the fiber router is, through PLC. This has been my default set up since years in several houses. Something related with the treadmill makes the link between both PLC devices unstable which ends up in internet issues. I have a backup for cable connectivity which is a wifi replicator and a specific wifi network for the devices I use for work (in other jobs I used to play with boards which required a testing network. So sometimes I have to use wifi instead of cable because the link between both PLC devices get unstable. It took me a while to detect the source of issues. After testing all the current current plugs at my office, I ended up finding one which makes the connectivity issues tolerable. Still I am searching for a solution here..

The takeaway is that the treadmill consumes quite some power and might have spurious looses that might turn network connectivity through PLC unstable. This is not the first time I suffer from this. The first mobile heat device I had at my office provoke the same effect.

Other points to consider

Some days I start walking and some others I walk after lunch on when I have back to back meetings. I tend to change the set up putting or removing the treadmill no more than once a day. Usually I have an additional set up change when I push down my Varidesk to work seated.

The standing desk converter I have is big enough to allow me to hold on to it when I do not have my hands on the keyboard. That have saved me from falling down during meetings more than once. Be careful, falling down is a real risk. Take precautions.

Get professional advice about walking with or without shoes. In my case, I walk without shoes. This decision might change in the future. My knees are awful due to injuries during my basketball times. Pay attention to the way you walk. When you get tired, your walking style changes and in might end up hurting.

My treadmill has a limit of 100 minutes. When it reaches that threshold, it stops. I was annoyed at first but it has ended up being a great thing. I used to work in cycles of 110 or 120 minutes but sometimes I loose track of time and this hard limit helps. While walking, my working cycles are shorter. 100 min which helps my concentration specially at the end of the day.

Obviously during meetings participants notice that I am walking. Be ready for questions and jokes. Having a treadmill is not mainstream yet. Ah, and do not fall while in a meeting.

Conclusions

At first I overdid it, got hurt and tired fast so my productivity in the afternoons dropped. In my second try I took it easier and the experience is getting better overtime. Six weeks after being back at using the treadmill again I am feeling better. I will soon be ready to increase the time walking and the type of activities I execute while on the treadmill.

I think it will take me another few weeks before the benefits for my health and shape become evident. I can see early signs though. So in general I find the experience positive so far although I expect to get better after a few more weeks when, in addition to the walking done in the treadmill, I have energy to complement such exercise with additional one on regular basis instead of just some days. The same applies to the level of concentration while doing the most demanding tasks.

The connectivity issues I am experiencing are unfortunate although tolerable. I need to find a solution.

So yes, I totally recommend to get yourself a treadmill. Results will show up sooner or later depending on your prior shape. I think that if you are in better shape than I was when I got it, which is not hard, results will be noticeable in a couple of months, probably less.

Categories: FLOSS Project Planets

Acro Media: Creating a Product Catalogue With Search API, Solr & Facets | Acro Media

Planet Drupal - Thu, 2021-04-15 15:00

Featuring a video from Acro Media’s YouTube tutorial series Tech Talk, this article will walk you through setting up an awesome Drupal Commerce product catalogue using Search API and Solr, and then adding various ways of filtering the results (product search, sorting options and Facet categories).

Ten steps to creating a product catalogue with Search API, Solr & Facets

These 10 steps will get you a Search API index using Solr, setup a View to display the results of the index, and then implemented 3 different ways to filter the results (search, sorting and Facets).

The end result of this guide will be a catalogue that functions in the same way as our Urban Hipster Drupal Commerce demo site’s catalogue. You can try it here. If you don’t already know why we use Search API, Solr and Facets for catalogues, check out this article to get up to speed.

Even though we’re going to be using products, once you understand how it works you’ll be able to apply the same method for other type of content such as a blog, videos, resources, and more. The datasource can change but the process is the same.

Let's get started! Follow along with this video or skip below for a written guide.

What you need before starting
  1. A running Solr server (Solr 6.4+)
    This tutorial assumes you have Solr running and can make a new core.

  2. Drupal 8 installed with the following modules:

    TIP:
    Get most of what you need quickly with Commerce Kickstart. Note that you will still need to install the Facets module after getting your Kickstart package.

    • Commerce
      composer require drupal/commerce
    • Search API
      composer require drupal/search_api
    • Solr
      NOTE: This module requires you're running Solr 6.4+ and PHP 7
      composer require drupal/search_api_solr
    • Facets
      composer require drupal/facets
Getting started
  1. Install/start Solr and add a new core that we’ll use later.

  2. Enable the Commerce, Search API, Solr and Facets modules.
Setup a basic Commerce store For this tutorial, get your site and basic store set up by doing the following:

  1. Add a product category taxonomy vocabulary that is at least 2 levels deep.
    If we use clothing as an example, we might have Men and Women as the first level, then t-shirts, shorts and shoes as the second level for each.

  2. Setup your basic Commerce store, product types and product variation types.
    If you’re new to Commerce, take a look at their documentation to get up and running quickly.

    NOTE: Make sure to add the taxonomy vocabulary you created as a ‘taxonomy reference’ field to your Product Type.

  3. Add 10 or more simple products for testing the catalogue as we go.

Add a Search API server and index Search API server

Admin: Configuration > Search and metadata > Search API
Admin menu path:
/admin/config/search/search-api

  1. Click ‘Add server’.

  2. Configure the server.
    1. Name your server and enable it.
    2. Set ‘Solr’ as the server ‘Backend’.
    3. Configure the Solr connector.
      The defaults are usually fine. The main things to add are:
      • Solr connector = ‘Standard’.
      • Solr core = Whatever you named your core.
    4. Under ‘Advanced’, check ‘Retrieve result data from Solr’.
    5. Look over the remaining settings and update if you need to.
Search API index

Admin:Configuration > Search and metadata > Search API
Admin menu path:
/admin/config/search/search-api

The index is where you set what data source is used by Search API. Eventually, you’ll also specify specific fields to be used for filtering the displayed results.

  1. Click ‘Add index’.

  2. Configure the index.
    1. Name your index.
    2. Data source should be ‘Product’
      This can be anything, but we’re creating a Commerce catalogue and so we want to use the store products.
    3. Select the server you just created.
    4. Save. Don’t add any fields for now, we’ll do that later.
    5. Go to the ‘View’ tab and index your results. This will index all of the products you have added so far.
Create a View for the catalogue

Admin:Structure > Views
Admin menu path:
/admin/structure/views

The View will use the data source we’ve identified in our index and allow us to create a catalogue with it, and then assign ways of filtering the catalogue results (i.e. a search field and/or facets).

  1. Create a new View.
    1. View Settings, select your index.
    2. Create a page (this will become our catalog).
  2. View Display settings.
    1. Format > Show
      Set as ‘Rendered entity’, then in the settings, set your product types to use a ‘Teaser’ view mode instead of the default.

      NOTE: If you don't see the 'Rendered entity' option, this seems to be a bug with Views and happens when you don't select your index before checking the 'Create a page' checkbox. To fix this, just refresh your page to start over. If that doesn't work, flush your caches.

      NOTE:You may need to create this view mode if it doesn’t already exist.

      NOTE:You could alternately use Fields instead of view modes, but I like to keep my product display settings all within the product type’s display settings. Then you can potentially customize the display per product type if you have more than one.
  3. Save the view .
    These basic settings should give us our overall catalog. You can confirm by previewing the view or visiting the page you just created.
Add Fulltext datasource fields for a catalog search field

Now we’ll start setting up a Fulltext search field to let our users filter results using a product search field. The first thing we need to do is add some datasource fields to our index that the search will use.

  1. Go to your Search API Index and go to the Fields tab.

  2. Add Fulltext fields that you would like to be searchable (such as Title, SKU, Category taxonomy name, etc.).
    Here’s an example for adding the title:
    1. Click ‘Add fields’.
    2. Under the ‘Product’ heading, click ‘Add’ beside the ‘Title’ field.

      NOTE: If you’re adding a different field instead, you may need to drill down further into the field by clicking ( + ) next to the field. For example, to make a taxonomy term a searchable field, you would go to Your Vocabulary > Taxonomy Term > Name .

    3. Click ‘Done’.
    4. Set the field ‘Type’ to ‘Fulltext’.
      This is an important step as only Fulltext fields are searchable with the user-entered text search we are currently setting up.

      NOTE: Under the fields section is a ‘Data Types’ section. You can open that to read information about each available type.

    5. Optionally change the ‘Boost’ setting.
      If you have more than one Fulltext field, the boost setting allows you to give a higher priority to specific fields for when the terms are being searched.

      For example, multiple products could have a similar title, but each product would have an individual SKU. In this case, SKU could be given a higher boost than title to make sure that search results based on the SKU come back first.
  3. Next, add another field for the ‘Published’ status.

  4. Once you’ve added this field, set it’s type as ‘Boolean’.

  5. Reindex your data (from within the index view tab).
Set up the catalogue search field within the catalogue View

We can now set up the actual search field that our customers will use to find products, and use the datasource fields we added to our index to do this.

  1. Go to your catalog View.

  2. Under ‘Filter criteria’.
    1. Add ‘Fulltext search’ and configure its settings.
      • Check ‘Expose this filter to visitors, to allow them to change it’.
        IMPORTANT:This is what gives the user the ability to use this search field.
      • ‘Filter type to expose’, set as ‘Single filter’.
      • ‘Operator’, set as ‘Contains any of these words’.
      • ‘Filter identifier’, optionally adds an identifier into the url to identify a search term filter.
        (i.e. yoursite.com/products?your-filter-identifier=search-term)
      • Apply/save your settings.
    2. Add ‘Published’ and configure it so that it is equal to true.
      This uses the field we added to the index earlier to make sure the product is actually published. Chances are you don’t want unpublished results shown to your customers.
  3. Under ‘Sort criteria’.
    1. Add ‘Relevance’.
    2. Configure so that the order is sorted ascending.
      This will show the more relevant results first (factoring in the boost you may have applied to your index fields).
  4. Now we need to expose the search field to our customers. To do this:
    1. Open the ‘Advanced’ section of your catalog view.
    2. In the ‘Exposed Form’ area.
      • Set ‘Exposed form in block’ to ‘Yes’.
        This creates a block containing a search field that we can place on the site somewhere.
      • Set ‘Exposed form style’ to ‘Basic’ and update the settings. For now, the settings you might change are customizing the submit button text and maybe including a reset button.
  5. Add the search block to your site.
    Admin menu path:/admin/structure/block

    1. In your preferred region, click the ‘Place block’ button.
    2. Find the Views block that starts with ‘Exposed form’ and click ‘Place block’.
      Its full name will be determined by you view’s machine name and page display name (i.e. Exposed form: products-page_1).
    3. Configure the block as you see fit, and save.
  6. Test your search!
    You should now be able to see the search field on your site frontend and try it out.
Add more datasource fields for sorting options

We can optionally sort the catalogue and search results with some additional sorting filters, such as sorting by Title, Price, Date added, etc. Let’s add the ability to sort our products by title with the option to choose ascending or descending order.

  1. Go to your Search API Index fields and add another 'Title' field the same as you did earlier. However, this time you want to change the field ‘Type’ to ‘String’. You should now have two Title fields added, one as ‘Fulltext’ and one as ‘String’.

    NOTE: The field type can be different depending on what field you’re adding. If you’re adding a sorting field such as Price > Number, you might use the ‘Decimal’ field type.

    TIP: I would recommend changing the label for the new Title field to something like ‘Title for sorting’ so that it’s easier to identify later. You could even change the fulltext Title label to ‘Title for search’, just to keep them organized and easy to understand.

  2. Reindex your data (from within the index view tab).

  3. Go to your catalogue View.
    1. Under ‘Sort criteria’.
      • Add the new title datasource and configure it.
        • Check ‘Expose this sort to visitors, to allow them to change it’.
          IMPORTANT: This is what gives the user the ability to use this sorting option.
        • Add a label for the filter
        • Set the initial sorting method.
      • Add any additional sorting fields if you added more.
    2. Open the settings for the ‘Exposed form style’ (within the view’s ‘Advanced’ section).
      • Check ‘Allow people to choose the sort order’.
      • Update the labels as you see fit.
    3. Save your view!
      Refresh your catalogue page and you should now see sorting options available in the search block that you added earlier.

      TIP: If you DO NOT see the sorting options, this is a bug and is easily fixed. All you need to do is remove the search block and then re-add it.

      TIP: You can place this block in multiple regions of your site and hide the elements you don’t want to see with CSS. This way you can have a block with the site search and no filters in your header, and then also have another block on your catalog pages that shows the sorting filters but no search field.
Add Facets to the catalogue

The filters we added earlier can only be used one at a time, however, often we want to filter the results based on a number of different options. For example, if I’m browsing an online store looking for shoes of a certain style and size, I don’t want to see everything else the store has to offer. I want to be able to go to a ‘shoe’ category, then pick the ‘type’ of shoe that I’m after, and finally pick the ‘size’ of shoe that’s relevant to me. I want to see all of the results that fit that criteria. Facets lets you use taxonomy (and other datasources) to achieve this.

Let’s add a Facet that uses the taxonomy vocabulary we created in the initial store setup. This will be our main catalogue menu for narrowing down the product results. Each facet that is created creates a block that we can add into any region of our template.

  1. Add a Search API index field for your taxonomy vocabulary. Set the field ‘Type’ as ‘String’.

    TIP: Like we did earlier, I would recommend renaming the label for this field to something like ‘Categories for Facet’.

  2. Reindex your data (from within the index view tab).

  3. Go to the Facets page.
    Admin: Configuration > Search and metadata > Facets
    Admin menu path:
    /admin/config/search/facets

    You should see a ‘Facet source’ available to use. When we created a View using our index, this is what added the Facet source here. Now that we have a source, we can create Facets to filter it.

  4. Click ‘Add facet’.
    1. Choose the ‘Facet source’ to use.
    2. Select the index ‘Field’ that this Facet will use (i.e. Categories for Facet, or whatever you labelled your field).
    3. Name your Facet (i.e. Categories).
  5. Configure the Facet.
    This will cover the basic settings that you will need. Start with this and then you can always play around with other settings later. Each setting has a pretty good description to help you understand what it does.
    1. Widget.
      Choose a ‘Widget’ for displaying the categories. For categories, I like to use ‘List of checkboxes’.
    2. Facet Settings.
      Check the following:
      • Transform entity ID to label.
      • Hide facet when facet source is not rendered.
      • URL alias as ‘cat’ (or whatever you like).
      • Empty facet behavior as ‘Do not display facet’.
      • Operator as ‘OR’.
      • Use hierarchy.
      • Enable parent when child gets disabled.
      • NOTE: the Facets Pretty Paths module can be used to give you nicer looking URL paths.
    3. Facet Sorting.
      Configure as you see fit. In this example, I would only check the following.These settings make sure that the taxonomy follows the same order that you have set within the vocabulary itself.
      • Sort by taxonomy term weight.
      • Sort order as ‘Ascending’.
    4. Save.
  6. Add the Facet block to your site.
    Admin: Structure > Block layout
    Admin menu path:
    /admin/structure/block

    1. In your preferred region, click the ‘Place block’ button.
    2. Find the ‘Categories’ facet block (or whatever you named it) and click ‘Place block’.
    3. Configure the block as you see fit.
    4. Save.
  7. Test your Facet!
    You should now see your Facet on the catalog page. Click the checkboxes and test out how it works!
One last thing...

The sites we've been building use the Facets Pretty Paths module for making nicer looking URLs with our catalog and filters. For a while we were plagued with a problem where, when the user selects a Facet category and then uses the sorting options, the Facets would uncheck and reset. This is obviously not good because the user is trying to sort the filtered down items, not the overall catalog. We need to be able to maintain the active facets when using the filters.

Luckily, a coworker came up with this nice little solutions that you can apply to your theme's .theme file. You just need to replace YOUR_THEME,YOUR-VIEW (i.e. products-page-1), and YOUR-PATH (i.e. products) in the code below. Ideally, this will be fixed within the module itself soon, but this will work while we wait.

/**
* Implements hook_form_alter().
*/
function YOUR_THEME_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Store - Product Listing view exposed form.
if ($form['#id'] == 'views-exposed-form-YOUR-VIEW') {
$current_path = \Drupal::request()->getRequestUri();

// If current path is within your catalog, correct the form action path.
if ((strpos($current_path, '/YOUR-PATH') === 0)) {
// Fix for views using facets with pretty paths enabled.
// Replace form action with current path to maintain active facets.
$form['#action'] = $current_path;
}
}
}

Done!

There you have it! You have now created a Search API index using Solr, setup a View to display the results of the index, and then implemented 3 different ways to filter the results (search, sorting and Facets). This is the start of an awesome product catalogue and you can expand on it with more datasource fields however you want. Cool!

Editor’s note: This article was originally published on July 12, 2018, and has been updated for freshness, accuracy and comprehensiveness.

 
Categories: FLOSS Project Planets

PyCharm: PyCharm Supports Django – you can too!

Planet Python - Thu, 2021-04-15 12:03
For those developers, whose daily work benefits from the Django framework.

As you probably know, the Django framework is built and maintained by community members. This might give you the impression that Django is effortlessly built by itself, but the truth is that the organization needs strong management and efficient communication. Making major Django releases every 8 months and bug fixes every month is no small task! That’s why the Django Fellowship program exists and why Django Software Foundation needs support from the community – both technical and financial.

Moreover, the Django Software Foundation supports community development and outreach projects such as Django Girls.

You can read more about the DSF activities here.

Support Django!

JetBrains is participating in a Django fundraising campaign – this year is the fifth iteration of this initiative. Over the past four years, JetBrains PyCharm has raised more than $140,000 for the Django Software Foundation.

How does it work?

During this campaign, you can buy a new individual license for PyCharm Professional for 30% off, and the full purchase price will go to the DSF’s general fundraising efforts and the Django Fellowship program.

This campaign will help the DSF maintain a healthy Django project and continue contributing to their various outreach programs.

Only with our support can Django make sure that the Web framework you base your work on can grow to be even better in the coming years. Don’t hesitate to share the link to the fundraising campaign with your fellow developers, who benefit from Django. Together we can support Django a lot!

Support Django!

Stay at the edge of your efficiency with Django and PyCharm

PyCharm always tries to support the latest features in Django and other technologies and make working with them easier, so that you can spend more time and energy solving the really interesting problems in your projects.

To help you get even more out of PyCharm and Django, we often prepare tutorials and arrange webinars on Django-related topics. Here are some useful resources we have for learning about working with Django projects:

Categories: FLOSS Project Planets

Aten Design Group: The body field is dead

Planet Drupal - Thu, 2021-04-15 11:56
The body field is dead jnettik Thu, 04/15/2021 - 09:56 Authoring Experience Drupal

Content authoring on the web has evolved. Compelling web content uses a variety of multimedia elements to engage users, tell stories, build brands, and share new ideas. Images, video clips, slideshows, static or parallax backgrounds, block quotes and text pullouts — more than ever, content creators need a tool that embraces an evolving medium and keeps pace with the author’s creativity. We believe Layout Paragraphs is that tool. But first, let’s all agree that the body field is dead.

What is the body field

Web editors and content authors who have been around over the last decade of digital media are intimately familiar with the body field. Many popular content management systems (looking at you, Drupal and Wordpress) feature a standard “post” or “content” type — like page, article, or blog post — right out of the box. These content types often have a couple of fields to fill out before you can publish your post, things like title, tags, friendly URL / slug, and of course body.

The body field, traditionally, is where all your content goes. In the early days of blogging and web publishing that was likely to be all or mostly text, but with time came images, videos, and eventually an array of other multimedia elements. And the body field adapted. Tokens became standard for plenty of web editors — cryptic chunks of text like [[nid:376 align:right]] that would be auto-magically replaced with other elements once you click Publish. WYSIWYG editors (What You See Is What You Get) started shipping with Insert image and Insert video buttons, and began including a variety of tools for encapsulating, aligning, and positioning lengths of text or various media elements. And while these accommodations started to connect content creators with the boundless possibilities of multimedia authoring, they were (and are) clumsy and unpredictable.

Structured content: Reduce, reuse, recycle

One major problem with all of these innovations is that once you click Publish, all that complex content still ends up in the body field — that is, saved into your database as one giant clump of complicated text, tokens, style codes, etc. If you’d like to publish another page with a similar look & feel, get ready to re-inject all of your tokens or go through the same WYSIWYG click-a-thon to reestablish your styles and layout. Thinking of producing a list of all the images used in your posts? Good luck! With all content mushed together into a single field, your site doesn’t “know” the difference between a paragraph of text, an image, or a video.

A structured approach to content organizes each individual element — a pane of text, an image, slideshow, video, or a “donate now” banner — as its own self-contained entity which, ideally, could then be placed within flexibly configured regions on a page. Creating other, similar pages then becomes as simple as swapping out individual elements or shifting them around between regions of a page. And libraries of reusable content elements become the norm — so that you’re now picking your images, videos, donate banners and more from lists of existing content or existing content styles, instead of trying to hunt down how you did something similar the last time.

Structuring your content into individual, reusable elements drives a lot of collateral benefits:

  • Ease of content creation. Authoring with a consistent set of components lets you focus more on content, hierarchy, and intent — instead of trying to remember how you got a video in there at all the last time.
  • Styling and restyling. Using discrete elements of content means that your HTML markup and CSS remains consistent across all of your various pages. When the time comes to update the look & feel of your website, changes made on one article page will “just work” on the rest of your articles and all of their elements.
  • Content migration. The day might arrive when you consider migrating your content to a newer platform or different software. Structured content makes that a snap: Each image, video, slideshow, or paragraph of text gets individually ported to its new home on the new platform. On the contrary, migrating a mess of markup, tokens, and style codes stored in a single body field means writing complex, custom code to recognize those items and deal with them appropriately — not a simple task.
  • Syndication. Want to feature your content in a collection via RSS or deploy it to an app with XML? With structured content apps and other websites can consume just the elements they want of your content (maybe the first paragraph, a title, an image, or a link) then display those elements appropriately according to their own styles — rather than just grabbing a few hundred lines of a single, messy body field and making do.
  • Libraries, lists, and cross-promotion. Want to see all the slideshows that appear in articles with a specific tag? Maybe a list of pull-quotes from your most recent blog posts? Structured content creates a world of opportunity around libraries, lists and cross-promotions.

Structuring content facilitates reuse, and it positions your content to go on living in a variety of platforms or a variety of presentations — long after you first click the Publish button.

The two faces of web content

Structuring content is an essential part of beautiful, intuitive digital authoring, but it’s only one side of the coin. The other side is putting an end to the two faces of your web content. Excepting some of the advances of modern WYSIWYG editors, web content has always had two very different faces: View and Edit.

The way content is edited and the way it’s presented are often strikingly different. Especially if you’re still holding on to “one giant body field” innovations like custom tokens, BBCode, Markdown, or short codes, it can take a handful of Preview to Edit to Preview roundtrips to get your content exactly how you want it. Even if you’ve made the move to structured content, a majority of web-based editors are marked by a dramatic difference between the “back end” and the “front end” — just one more digital convention getting between inspired authors and publishing beautiful content easily.

The king is dead, long live the king

The body field is dead. It’s taken center stage in publishing digital content for long enough. Plenty of web products (Medium and Notion, to name a couple) have driven nails in that coffin for publishers creating content on those specific platforms. But what about content creators and web editors working within their organizations’ websites, in custom web applications where content authoring is just one of several important features? What about you, and your organization’s website? What’s next for your web application?

For Drupal websites, we think Layout Paragraphs is what’s next. It was first released to the Drupal community nearly a year ago, and has been the beneficiary of ambitious development ever since.

The Layout Paragraphs module makes it dead simple for authors to create robust, multimedia content from a library of available components. It offers intuitive drag-and-drop controls for managing content flow and layout, and with appropriate styling can bring the two faces of web content — View and Edit — closer than ever before. We built Layout Paragraphs to embrace the future of multimedia content authoring and to solve the problems we watch clients work through every day.

You can watch a short, two-minute demo of Layout Paragraphs here, or follow the instructions in that post to see it in action for yourself.

James Nettik
Categories: FLOSS Project Planets

Python for Beginners: Iterating over dictionary in Python

Planet Python - Thu, 2021-04-15 10:40

Dictionaries are one of the most frequently used data structures in python. It contains data in the form of key value pairs. While processing the data with dictionaries, we may need to iterate over the items in the dictionary to change the values or read the values present in the dictionary. In this article, we will see various ways for iterating over dictionary in python.

Iterating over a dictionary using for loop

As we iterate through lists or tuples using for loops in python, we can also iterate  through a python dictionary using a for loop.

When we try to iterate over a dictionary using for loop,it implicitly calls __iter__() method. The __iter__() method returns an iterator with the help of which we can iterate over the entire dictionary. As we know that dictionaries in python are indexed using keys, the iterator returned by __iter__() method iterates over the keys in the python dictionary.

So, with a for loop, we can iterate over and access all the keys of a dictionary as follows.

myDict={"name":"PythonForBeginners","acronym":"PFB","about":"Python Tutorials Website"} print("The dictionary is:") print(myDict) print("The keys in the dictionary are:") for x in myDict: print(x)

Output:

The dictionary is: {'name': 'PythonForBeginners', 'acronym': 'PFB', 'about': 'Python Tutorials Website'} The keys in the dictionary are: name acronym about

In the output we can see that all the the all the keys have been printed. In the for loop the iterator x iterates over all the keys in the dictionary which are then printed.

Having obtained the keys of the dictionary using for loop, we can also iterate over the values in the dictionary as follows.

myDict={"name":"PythonForBeginners","acronym":"PFB","about":"Python Tutorials Website"} print("The dictionary is:") print(myDict) print("The values in the dictionary are:") for x in myDict: print(myDict[x])

Output:

The dictionary is: {'name': 'PythonForBeginners', 'acronym': 'PFB', 'about': 'Python Tutorials Website'} The values in the dictionary are: PythonForBeginners PFB Python Tutorials Website

In the code above, we have simply obtained an iterator which iterates over the keys in the and then we have accessed the values associated to the keys using the syntax dict_name[key_name] and then the values are printed.

Iterate over keys of a  dictionary

We can use the keys() method to iterate over keys of a dictionary. The keys() method returns a list of keys in the dictionary when invoked on a dictionary and then we can iterate over the list to access the keys in the dictionary as follows.

myDict={"name":"PythonForBeginners","acronym":"PFB","about":"Python Tutorials Website"} print("The dictionary is:") print(myDict) print("The keys in the dictionary are:") keyList=myDict.keys() for x in keyList: print(x)

Output:

The dictionary is: {'name': 'PythonForBeginners', 'acronym': 'PFB', 'about': 'Python Tutorials Website'} The keys in the dictionary are: name acronym about

We can also access values associated with the keys of the dictionary once we have the keys in the list as follows.

myDict={"name":"PythonForBeginners","acronym":"PFB","about":"Python Tutorials Website"} print("The dictionary is:") print(myDict) print("The values in the dictionary are:") keyList=myDict.keys() for x in keyList: print(myDict[x])

Output:

The dictionary is: {'name': 'PythonForBeginners', 'acronym': 'PFB', 'about': 'Python Tutorials Website'} The values in the dictionary are: PythonForBeginners PFB Python Tutorials Website Iterate over values of a dictionary in python

If we only want to access the values in the dictionary, we can do so with the help of the values() method.The values() method when invoked on a dictionary returns a list of all the values present in the dictionary. We can access the values in the dictionary using values() method and for loop as follows.

myDict={"name":"PythonForBeginners","acronym":"PFB","about":"Python Tutorials Website"} print("The dictionary is:") print(myDict) print("The values in the dictionary are:") valueList=myDict.values() for x in valueList: print(x)

Output:

The dictionary is: {'name': 'PythonForBeginners', 'acronym': 'PFB', 'about': 'Python Tutorials Website'} The values in the dictionary are: PythonForBeginners PFB Python Tutorials Website

In the output, we can see that all the values present in the dictionary are printed one by one.

Iterating over items in a dictionary in python

We can iterate over and access the key value pairs using the items() method. The items() method when invoked on a dictionary, returns a list of tuples which have keys and values as pairs. Each tuple has a key on its 0th index and the value associated with the key is present on the 1st index of the tuple. We can access the key value pairs using items() method as shown below.

myDict={"name":"PythonForBeginners","acronym":"PFB","about":"Python Tutorials Website"} print("The dictionary is:") print(myDict) print("The items in the dictionary are:") itemsList=myDict.items() for x in itemsList: print(x)

Output:

The dictionary is: {'name': 'PythonForBeginners', 'acronym': 'PFB', 'about': 'Python Tutorials Website'} The items in the dictionary are: ('name', 'PythonForBeginners') ('acronym', 'PFB') ('about', 'Python Tutorials Website')

Along with iterating the items in the dictionary using the items() method,we can also iterate over keys and values of  a dictionary using two iterators in the for loop as follows.

myDict={"name":"PythonForBeginners","acronym":"PFB","about":"Python Tutorials Website"} print("The dictionary is:") print(myDict) itemList=myDict.items() print("The key value pairs in the dictionary are:") for x,y in itemList: print(x,end=":") print(y)

Output:

The dictionary is: {'name': 'PythonForBeginners', 'acronym': 'PFB', 'about': 'Python Tutorials Website'} The key value pairs in the dictionary are: name:PythonForBeginners acronym:PFB about:Python Tutorials Website

In the above program, the first iterator iterates over the keys in the dictionary and the second iterator iterates over the respective values associated with those keys which are present in the form of tuple containing key value pairs in the list returned by items() method. 

Conclusion

In this article, we have seen various ways to iterate over the data in dictionaries. We have seen how to access the keys and values of the dictionary using for loop and inbuilt methods like keys(), values() and items(). We can also write the programs used in this article with exception handling using python try except to make the programs more robust and handle errors in a systematic way. Stay tuned for more informative articles.

The post Iterating over dictionary in Python appeared first on PythonForBeginners.com.

Categories: FLOSS Project Planets

Drudesk: How to prevent website spam using Drupal spam prevention modules

Planet Drupal - Thu, 2021-04-15 10:19

Spam.

This word contains so much pain and headache for any site owner. It is not possible to 100% eradicate spam from your website. However, it is possible to reduce these rates to a minimum, provided that you know how to prevent website spam.

Today we are going to tell you about the best ways to stop website spam. Our web maintenance company has chosen 6 handy anti-spam Drupal modules. You have to choose the one that suits you best and add it to the site.

Categories: FLOSS Project Planets

Community Working Group posts: 2021 Aaron Winborn Award Winner: AmyJune Hineline

Planet Drupal - Thu, 2021-04-15 08:38

During DrupalCon North America 2021, the members of the Drupal Community Working Group announced the winner of the 2021 Aaron Winborn Award, AmyJune Hineline (volkswagenchick).  

Since joining the Drupal community in 2015 after a career change, AmyJune has made an impact in multiple aspects of the community. She is a core mentor, helps organize multiple Drupal events around North America, and is a tireless advocate for accessibility and inclusivity in the community. In addition, she is one of the organizers of A11yTalks, a member of the Community Health Team, a documentation contributor, and has been credited in over 700 issues in the past year. Much of her work is sponsored by her employer, Kanopi Studios

Multiple people nominated AmyJune for this award. Here are some of the things they said:

"AmyJune has worked tirelessly for years to encourage contribution to the Drupal project from people with ALL levels of experience and skill sets. She creates a welcoming environment for anyone interested in contributing and makes the process less intimidating."

"She shares her knowledge freely and frequently, and also shares prolifically on social media to help others spread the word about their community work and celebrate successes."

"AmyJune is dedicated to the Drupal project on a level I have personally never seen before."

"AmyJune encourages accessibility and inclusiveness in all of her interactions within the community."

"I've never seen someone more dedicated to community and especially the Drupal community."

"I'm new to the Drupal Community (I joined 5 months ago), and I'm also new to the tech industry, and of course, the onboarding with no coding skills whatsoever has been quite a challenge. In this brief period, AmyJune has been an inspiring role model to look up to."

This year, there were 29 individuals nominated for the award. In the coming weeks, the CWG will be contacting all nominees to let them know of their nomination and thank them for their continued work in the community.

In addition to the physical award shipped to AmyJune, she was also provided with a free ticket to DrupalCon Global which she graciously donated to a deserving community member. The physical award that was hand-crafted by Drupal community member Bo Shipley (simplyshipley).  

The award is named after a long-time Drupal contributor who lost his battle with ALS in 2015. This award recognizes an individual who, like Aaron, demonstrates personal integrity, kindness, and an above-and-beyond commitment to the Drupal project and community. Previous winners of the award are Cathy Theys, Gabór Hojtsy, Nikki Stevens, Kevin Thull, Leslie Glynn, and Baddý Breidert. Current CWG members, along with previous winners, selected the winner based on nominations submitted by Drupal community members.

Nominations for the 2022 award will open in early 2022.
 

Categories: FLOSS Project Planets

Stack Abuse: Radix Sort in Python

Planet Python - Thu, 2021-04-15 08:30
Introduction to Radix Sort

The radix (or base) is the number of digits used to represent numbers in a positional numeral system. For the binary system, the radix is 2 (it uses only two digits - 0 and 1). For the decimal system, the radix is 10 (it uses ten digits to represent all numbers - from 0 to 9).

A positional numeral system is, in simple terms, a number writing system, where the weight (or the value) of a digit is determined by its position. For example, in the number 123, 1 has more value than 3 because it's in position that denotes hundreds, and the 2 is in the tens.

Radix Sort can be used to lexicographically sort many types of data - integers, words, emails, but is mainly used to sort collections of integers and strings (that are mapped to appropriate integer keys).

It's a non-comparative sorting algorithm, meaning that it doesn't sort a collection by comparing its individual elements, but rather uses the inherent nature of the data its sorting to sort faster - it sorts data based on their radix.

Comparative sorting algorithms have the best case time complexity of O(nlogn), which is comparatively worse to linear execution time (O(n+k)) of non-comparative algorithms.

For example, let n be the number of elements to be sorted, and k is the range of allowed element values.

Counting Sort (a popular non-comparative algorithm) has the complexity of O(n+k) when the k is in the range from 1..n. But, if elements range from 1..n², then the complexity rises to O(n²), which is worse than any comparative sorting algorithm.

Counting Sort has the potential to be significantly faster than other popular comparative algorithms, though, only if a certain condition was fulfilled.

The idea of the Radix Sort is to upgrade Counting Sort so that it maintains the linear time complexity even if the range of elements' values drastically exceeds the number of elements.

In fact, Radix Sort inherently uses Counting Sort as the main subroutine, with a few tweaks to overcome the issues that arise with an incrased range of elements' values.

Counting Sort Algorithm

In order to get a grasp of Radix Sort, we'll have to delve into Counting Sort first, implement it and observe the downfall with an increased number of element values.

Why Use Counting Sort in the Radix Sort?

Counting sort is a stable, non-comparative sorting algorithm, and it is mainly used to sort integer arrays. All of these characteristics are important for its use in Radix Sort. You can use other algorithms as the subroutine, as long as they have these characteristics, though, Counting Sort is the most natural matchup.

Radix Sort needs to maintain a relative order of elements with the same key values in the input array while sorting the same place value digits, therefore, our main subroutine by definition needs to be some sort of stable sorting algorithm:

Non-comparative sorting algorithms generally have linear complexity, so they will have less impact on the complexity of the Radix Sort.

How Does the Counting Sort Work?

Let's take a look at an unsorted integer array, which we'll sort using Counting Sort:

I = [2, 2, 0, 6, 1, 9, 9, 7]

Counting Sort works by counting the number of elements, that fit a distinct key value, and then calculates the positions of each key.

First of all, we'll find the maximum element in the input array - max = 9.

Then, we'll create an auxiliary array with max+1 elements. This is the count array (C), which will be used to store the number of occurrences of each element in the input array.

Initially, all counts are initialized to 0:

C = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # Count array #indices: 0 1 2 3 4 5 6 7 8 9

Now, we need to go through the following steps:

1. Traverse the input array and increase the corresponding count for every element by 1

For example, if we come across an element with the value of 2 in the input array (I), we add 1 to the element with the index 2 in the count array:

I = [2, 2, 0, 6, 1, 9, 9, 7] # The first element is 2 ^ C = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0] # We increase count of 2nd element by 1 #indices: 0 1 2 3 4 5 6 7 8 9

After this step, the count array will store the number of occurrences of each element in the input array:

C = [1, 1, 2, 0, 0, 0, 1, 1, 0, 2] #indices: 0 1 2 3 4 5 6 7 8 9 # Element 0 has 1 occurrence # Element 1 has 1 occurrence # Element 2 has 2 occurrences # Element 3 has no occurrences...

2. For each element in the count array, sum up its value with the value of all its previous elements, and then store that value as the value of the current element:

C = [1, 2, 4, 4, 4, 4, 5, 6, 6, 8] #indices: 0 1 2 3 4 5 6 7 8 9 # Element 0 = 1 # Element 1 = 1 + 1 # Element 2 = 1 + 1 + 2 # Element 3 = 1 + 1 + 2 + 0 #...

This way, we are storing the cumulative sum of the elements of the count array, on each step.

3. Calculate element position based on the count array values

To store this sorted sequence, we'll need to create a new array. Let's call it the output array (O), and initialize it with k zeros, where k is the number of elements in the input array:

O = [0, 0, 0, 0, 0, 0, 0, 0] // Initialized output array #indices: 0 1 2 3 4 5 6 7

For each element I[i] (starting from the end) in the input array:

  1. Find the index in the count array that is equal to the value of the current element I[i]
    • That's the element C[j] where j=I[i]
  2. Subtract 1 from the value of the C[i]
    • Now we have newValue = C[i]-1
  3. Store the I[i] to the O[newValue]
  4. Update the C[i] with the newValue

In the end, the output array contains the sorted elements of the input array!

Implementing Counting Sort in Python

Now, with all that out of the way - let's go ahead an implement Counting Sort in Python:

def countingSort(inputArray): # Find the maximum element in the inputArray maxEl = max(inputArray) countArrayLength = maxEl+1 # Initialize the countArray with (max+1) zeros countArray = [0] * countArrayLength # Step 1 -> Traverse the inputArray and increase # the corresponding count for every element by 1 for el in inputArray: countArray[el] += 1 # Step 2 -> For each element in the countArray, # sum up its value with the value of the previous # element, and then store that value # as the value of the current element for i in range(1, countArrayLength): countArray[i] += countArray[i-1] # Step 3 -> Calculate element position # based on the countArray values outputArray = [0] * len(inputArray) i = len(inputArray) - 1 while i >= 0: currentEl = inputArray[i] countArray[currentEl] -= 1 newPosition = countArray[currentEl] outputArray[newPosition] = currentEl i -= 1 return outputArray inputArray = [2,2,0,6,1,9,9,7] print("Input array = ", inputArray) sortedArray = countingSort(inputArray) print("Counting sort result = ", sortedArray)

Running the code above will yield us the following output:

Input array = [2, 2, 0, 6, 1, 9, 9, 7] Counting sort result = [0, 1, 2, 2, 6, 7, 9, 9] Counting Sort Complexity

The time complexity of the counting sort is O(n+k), where n is the number of elements in the input array, and k is the value of the max element in the array.

The problem occurs when the value of the largest element drastically exceeds the number of elements in the array. As the k approaches n², the time complexity gets closer to O(n²), which is a horrible time complexity for a sorting algorithm.

This is where Radix Sort kicks in.

Radix Sort Algorithm

Instead of counting the elements by their distinct key value - Radix Sort groups digits by their positional value and performing Counting Sort in each group. The starting position can vary - LSD (Least Significant Digits) or MSD (Most Significant Digits) are two common ones, and accordingly, these variations of Radix Sort are called LSD Radix Sort and MSD Radix Sort.

Let I = [2, 20, 61, 997, 1, 619] be the input array that we want to sort:

We'll focus on LSD Radix Sort.

Radix Sort Algorithm

The steps taken by Radix Sort are fairly straighforward:

  1. Find the maximum element in the input array - max = 997
  2. Find the number of digits in the max element - D = 3
  3. Initialize the place value to the least significant place - placeVal = 1
  4. For D times do:
    1. Perform the counting sort by the current place value
    2. Move to the next place value by multiplying placeVal by 10

Implementing Radix Sort in Python

And finally, with that out of the way, let's implement Radix Sort in Python:

def countingSortForRadix(inputArray, placeValue): # We can assume that the number of digits used to represent # all numbers on the placeValue position is not grater than 10 countArray = [0] * 10 inputSize = len(inputArray) # placeElement is the value of the current place value # of the current element, e.g. if the current element is # 123, and the place value is 10, the placeElement is # equal to 2 for i in range(inputSize): placeElement = (inputArray[i] // placeValue) % 10 countArray[placeElement] += 1 for i in range(1, 10): countArray[i] += countArray[i-1] # Reconstructing the output array outputArray = [0] * inputSize i = inputSize - 1 while i >= 0: currentEl = inputArray[i] placeElement = (inputArray[i] // placeValue) % 10 countArray[placeElement] -= 1 newPosition = countArray[placeElement] outputArray[newPosition] = currentEl i -= 1 return outputArray def radixSort(inputArray): # Step 1 -> Find the maximum element in the input array maxEl = max(inputArray) # Step 2 -> Find the number of digits in the `max` element D = 1 while maxEl > 0: maxEl /= 10 D += 1 # Step 3 -> Initialize the place value to the least significant place placeVal = 1 # Step 4 outputArray = inputArray while D > 0: outputArray = countingSortForRadix(outputArray, placeVal) placeVal *= 10 D -= 1 return outputArray input = [2,20,61,997,1,619] print(input) sorted = radixSort(input) print(sorted)

Running the code above will yield us the following output:

[2, 20, 61, 997, 1, 619] [1, 2, 20, 61, 619, 997] Radix Sort Complexity

As we stated before, Radix Sort has linear time complexity. If we use Counting Sort as the main subroutine, the complexity of radix sort is O(d(n+k)). That is because we are executing the counting sort d times, and the complexity of the Counting Sort itself is O(n+k).

Conclusion

Radix sort is a great sorting algorithm to use in some specific cases. Some benchmarks have even shown that radix sort can execute up to 3 times faster than other, more general-purpose sorting algorithms.

It shines when the input array has shorter keys, or the range of the element values is smaller. But has poor space complexity in other cases, when the range of element values is quite large and elements have too many digits in their representation.

That is the main reason why the radix sort is not as widely used as some other types of sorting algorithms, even if it has linear time complexity.

Categories: FLOSS Project Planets

remotecontrol @ Savannah: How Amazon Strong-Arms Partners Using Its Power Across Multiple Businesses

GNU Planet! - Thu, 2021-04-15 08:17

https://www.wsj.com/articles/amazon-strong-arms-partners-across-multiple-businesses-11618410439

"Amazon.com Inc. last year told smart-thermostat maker Ecobee it had to give the tech giant data from its voice-enabled devices even when customers weren’t using them."

"Amazon responded that if Ecobee didn’t serve up its data, the refusal could affect Ecobee’s ability to sell on Amazon’s retail platform..."

Categories: FLOSS Project Planets

Programiz: Python Program to Randomly Select an Element From the List

Planet Python - Thu, 2021-04-15 07:31
In this example, you will learn to select a random element from the list.
Categories: FLOSS Project Planets

Programiz: Python Program Read a File Line by Line Into a List

Planet Python - Thu, 2021-04-15 07:10
In this example, you will learn to read a file line by line into a list.
Categories: FLOSS Project Planets

Season of KDE 2021 Report

Planet KDE - Thu, 2021-04-15 07:02
Season of KDE 2021 Status Report

This year I participated SoK as mentor for KWeather and Kalk. Now the work has been done, let me sum up the new features we bring to the projects.

KWeather

When the project name is KWeather, the actual code is committed to KWeatherCore, a Weather library. We decided to add weather alerts functionality to KWeatherCore, possibly easing the difficulty later if we want to develop a weather alerts daemon.

The data source is from metroelogy institutes around the world. Most of them provide CAP protocol for alerts. So the main goal is to write two parsers, one for CAP feed parsing and other for the CAP parsing. Anjani Kumar finished classes representing CAP feed entry and CAP message, as well as the CAP parser. Nikunj Goyal is supposed to work on feed parser and some of the daemon code. But due to various reasons, he wrote the AlertManager class which is an utility class. I wrote the feed parser and finished most of the documentation.

Since the lack of man hours, we weren’t able to finish the promised daemon. However the library is working as expected. We use config files (in json format) to avoid hardcoding different formats of CAP feed. So in the future we can support more countries without edit our code (and releasing new library version).

Kalk

Kalk is calculator for Plasma Mobile, this SoK we’re bringing binary mode to it.

Though as simple as the project name suggests, in the middle of the SoK we decided to switch from primitive double type to GMP and MPFR for our base type. Thankfully we’re using Bison/Flex for our math engine so swithing to multi-precision big number type doesn’t require use to rewrite Kalk again, wrapper classes still needs to be created. We re-used Knumber from KCalc. Since it’s a in-source library for KCalC, and lacking some helper functions Kalk needs, it has been copied to Kalk and modified since. Rohan Asokan wrote binary number type wrapper for Knumber (though later reverted because of preference for native GMP/MPFR binary <-> string converting functions), and math engine supports simple binary calculations. He also managed to add UI for binary calculator using Kirigami.

Date calculator was originally planned, but I decided to drop it eventually. Kalk is a simple calculator, I don’t want it to be bloat. Rohan Asokan did have a prototype for it though.

Categories: FLOSS Project Planets

Civic UK: Implementing DWP GOV.UK cookie consent pattern in Drupal

Planet Drupal - Thu, 2021-04-15 06:49
In this blog post we provide instructions on how to enable, configure and use the DWP consent pattern in a Drupal 8/9 based website.
Categories: FLOSS Project Planets

Programiz: Python Program to Print Output Without a Newline

Planet Python - Thu, 2021-04-15 06:28
In this example, you will learn to print output without a newline.
Categories: FLOSS Project Planets

Programiz: Python Program to Get a Substring of a String

Planet Python - Thu, 2021-04-15 06:17
In this example, you will learn to get a substring of a string.
Categories: FLOSS Project Planets

Programiz: Python Program to Get the Last Element of the List

Planet Python - Thu, 2021-04-15 05:30
In this example, you will learn to get the last element of this list.
Categories: FLOSS Project Planets

Hilbert Transform

Planet KDE - Thu, 2021-04-15 05:14

The next release 2.9 will again come with many very useful and interesting new features. Today we want to talk about a new feature in the area of the data analysis that has been included into LabPlot’s master branch recently.

Though it is possible in LabPlot to access many different computer algebra systems and programming languages with a plethora of packages relevant in scientific communities, it is sometimes useful and desired to perform the analysis of data in a more visual and interactive way. For this kind of analysis LabPlot already supports algorithms and computations like the Fourier Transformation, smoothing, interpolations, Fourier filter, etc (see this blog post for a couple of examples). To this list we have now added the Hilbert Transform.

The Hilbert Transform has many applications, especially in signal processing. Below is an example produced in LabPlot that shows the time response of a super regenerative receiver to an ultra-wideband (very short) pulse consisting of few oscillating cycles enclosed within a Gaussian-like envelope (for high-Q receivers) or within a bilateral exponential envelope (for low-Q receivers).



In this example, the use of the Hilbert Transform helps you visualize and confirm the envelope shape and to find some signal features, like the position and the value of the maximum envelope point, which would be very difficult to determine otherwise.

The current development versions (i.e. the code being finalized and prepared for the next release) is available from our download section and can already be used to try out this new feature.

Categories: FLOSS Project Planets

Better Calendar, Better Kickoff and... Merge Requests?

Planet KDE - Thu, 2021-04-15 05:10

Better Calendar, Better Kickoff and... Merge Requests?

Categories: FLOSS Project Planets

Single-shot signal/slot connections

Planet KDE - Thu, 2021-04-15 05:00

Sometimes it’s useful to establish a connection between a signal and a slot that should be activated only once. This is not how signal/slot connections normally behave. Remember that, when a connection is established, it will stay active until:

  • the connection is explicitly disconnected; or
  • the sender object is destroyed; or
  • the receiver object is destroyed.

So, if we need such a single-shot connection, how do we go about it? A possible solution is to connect our signal to a small helper function (for instance, a lambda) that disconnects the connection, then calls the actual slot. This is it, in pseudocode:

// Trying to make // connect(sender, &Sender::signal, receiver, &Receiver::slot) // behave as single-shot connection auto singleShot = [receiver, connection](parameters) { QObject::disconnect(connection); // WHOPS, we don't have this yet! receiver->slot(parameters); }; connection = connect(sender, &Sender::signal, receiver, std::move(singleShot));

There’s a semantic problem with this code: the connection object is created after the lambda. But we need its value in the lambda, to be able to disconnect it! Fixing this requires us to introduce a little indirection, but it’s doable:

auto connection = std::make_unique<QMetaObject::Connection>(); auto connectionPtr = connection.get(); auto singleShot = [receiver, connection = std::move(connection)](parameters) { QObject::disconnect(*connection); receiver->slot(parameters); }; *connectionPtr = connect(sender, &Sender::signal, receiver, std::move(singleShot)));

This is…quite annoying to write. I certainly don’t want to type all of that every time I need a single-shot connection, and trying to make it generic is super tricky for new users of Qt.

We can do better!

Enter Qt 6.0!

In Qt 6, I have added the convenience Qt::SingleShotConnection connection flag that you can pass as the fifth argument of QObject::connect (optionally combining it with the other connection types):

connect(sender, &Sender::signal, receiver, &Receiver::slot, static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));

The static_cast isn’t technically necessary, in this case. But it becomes necessary, should we want to also pass some other arguments (for instance, if we want the connection to be queued as well as single-shot). This closed a long-standing and very voted feature request. Sometimes, by removing the pebble in your shoe, you make many other people happy.

And for Qt 5?

I can’t add the same feature to Qt 5, as Qt 5 development is closed for new features.

However, I’ve also reimplemented the solution shown above in KDToolBox and packaged it with a convenient API:

KDToolBox::connectSingleShot(sender, &Sender::signal, receiver, &Receiver::slot); sender->causeSignalEmission(); // calls the slot, and breaks the connection sender->causeSignalEmission(); // does NOT call the slot

KDToolBox is KDAB’s collection of miscellaneous useful C++ classes and stuff. You can download it from our GitHub repository here.

Have fun!

About KDAB

If you like this blog and want to read similar articles, consider subscribing via our RSS feed.

Subscribe to KDAB TV for similar informative short video content.

KDAB provides market leading software consulting and development services and training in Qt, C++ and 3D/OpenGL. Contact us.

The post Single-shot signal/slot connections appeared first on KDAB.

Categories: FLOSS Project Planets

Python Bytes: #229 Has one of your dependencies died?

Planet Python - Thu, 2021-04-15 04:00
<p><strong>Watch the live stream:</strong></p> <a href='https://www.youtube.com/watch?v=PvBRXsGTXn4' style='font-weight: bold;'>Watch on YouTube</a><br> <br> <p><strong>About the show</strong></p> <p>Sponsored by us! Support our work through:</p> <ul> <li>Our <a href="https://training.talkpython.fm/"><strong>courses at Talk Python Training</strong></a></li> <li><a href="https://pragprog.com/titles/bopytest/python-testing-with-pytest/"><strong>pytest book</strong></a></li> <li><a href="https://www.patreon.com/pythonbytes"><strong>Patreon Supporters</strong></a></li> </ul> <p>Special guests: </p> <ul> <li><a href="https://twitter.com/gwen_faraday"><strong>Gwendolyn Faraday</strong></a></li> <li>Gwendolyn’s <strong><a href="https://www.youtube.com/channel/UCxA99Yr6P_tZF9_BgtMGAWA">YouTube</a></strong></li> </ul> <p><strong>Brian #1:</strong> <a href="https://nedbatchelder.com/blog/202104/coveragepy_and_thirdparty_code.html"><strong>Coverage.py</strong></a> <a href="https://nedbatchelder.com/blog/202104/coveragepy_and_thirdparty_code.html"><strong>(5.6b1)</strong></a> <a href="https://nedbatchelder.com/blog/202104/coveragepy_and_thirdparty_code.html"><strong>and third-party code</strong></a></p> <ul> <li>Problems <ul> <li>If you put your virtual environment in the same directory as your code, and try to run coverage, it’s tricky to get coverage to not attempt to cover everything in your venv also.</li> <li>Or even just running <code>coverage run -m pytest</code> with no <code>--source</code> specified, it just kinda reports on everything, even stuff in <code>site-packages</code>, not just your code.</li> </ul></li> <li>Solution <ul> <li><code>pip install coverage==5.6b1</code></li> <li>As of 5.6b1, coverage knows where third party code is and doesn’t measure it.</li> </ul></li> <li>Super awesome</li> <li>Also, it’s still beta. Net wants help testing it out and making sure it works right.</li> <li>I’m curious if it still works right with pytest plugins and such, so I’ll be testing a bunch of stuff to make sure it still makes sense. </li> </ul> <p><strong>Michael #2:</strong> <a href="https://github.com/piku/piku"><strong>So you want your own PaaS? Piku!</strong></a></p> <ul> <li>via Ian Mauer</li> <li>The tiniest PaaS you've ever seen. </li> <li>Piku allows you to do git push deployments to your own servers. </li> <li>Allows you do <code>git push</code> deployments to your own servers.</li> <li>Motivation: I kept finding myself wanting an Heroku/CloudFoundry-like way to deploy stuff on a few remote ARM boards and <a href="https://github.com/rcarmo/raspi-cluster">my Raspberry Pi cluster</a></li> <li><strong>Core values</strong> <ul> <li>Runs on low end devices.</li> <li>Accessible to hobbyists and K-12 schools.</li> <li>~1,000 lines readable code.</li> <li>Functional code style.</li> <li>Few (single?) dependencies</li> <li><a href="https://12factor.net">12 factor app</a>.</li> <li>Simplify user experience.</li> <li>Cover 80% of common use cases.</li> <li>Sensible defaults.</li> <li>Leverage distro packages in Raspbian/Debian/Ubuntu (Alpine and RHEL support is WIP)</li> <li>Leverage standard tooling (<code>git</code>, <code>ssh</code>, <code>uwsgi</code>, <code>nginx</code>).</li> <li>Preserve backwards compatibility where possible</li> </ul></li> </ul> <p><strong>Gwen #3:</strong> <strong><a href="https://web3py.readthedocs.io/en/stable/#">Web3.py</a></strong></p> <ul> <li>Web3.py - Library for building Dapps in Python with Ethereum <ul> <li>Need to connect to a blockchain service (e.g. BlockCypher) or <a href="https://www.trufflesuite.com/docs/ganache/overview">run your own locally</a></li> </ul></li> <li>Can create contracts and interact with them or get general blockchain information in Python</li> <li><a href="https://vyper.readthedocs.io/en/stable/">Vyper</a> is a pythonic language for the blockchain that can be used for smart contracts</li> </ul> <p><strong>Brian #4:</strong> <a href="https://deadpendency.com/"><strong>Deadpendency</strong></a></p> <ul> <li>Suggested by Johannes Lippmann</li> <li>In <a href="https://pythonbytes.fm/episodes/show/227/no-more-awaiting-async-comes-to-sqlalchemy">episode 277</a> we talked about the Snyk (Python) Package Advisor which tells us how healthy a python package is.</li> <li><a href="https://deadpendency.com/">Deadpendency</a> is a similar thing, but tells you about the health of the packages you depend on. It’s a GitHub app that runs on PRs and commits.</li> <li>Let’s say someone has a PR that adds a dependency. The PR checks will include a health check of the new dependency. </li> <li>What’s more, on each commit or PR, all of your dependencies will be checked.</li> <li>Checks for: <ul> <li>no recent releases (warn at 18 months, fail at 24 months)</li> <li>no recent commits (warn at 12 months, fail at 18 months)</li> <li>few yearly commits (warn at 2)</li> <li>archived repository (fail)</li> <li>repository is a fork (warn)</li> <li>package deprecated (fail)</li> <li>single recent author (warn)</li> </ul></li> <li>Everything is configurable</li> <li>Temporary problems: <ul> <li>only supports requirements.txt and Pipfile, for Python</li> <li>Kinda need it to support pyproject.toml, maybe setup.py</li> <li>I’d like to be able to just run this on a project without having to have a commit or push trigger it, to try it out. I’ve got some CI tools that allow that. Maybe it’s common for them to not. not sure.</li> </ul></li> <li>Also be neat if: <ul> <li>it did the snyk checks for at least security and maintenance on the dependency. Not just release and commit frequency.</li> </ul></li> <li>Bottom line: <ul> <li>Neat idea. Waiting for support for pyproject.toml</li> </ul></li> </ul> <p><strong>Michael #5:</strong> <a href="https://martinheinz.dev/blog/46"><strong>All The Important Features and Changes in Python 3.10</strong></a></p> <ul> <li>Python 3.10 beta is coming soon. What will be in it? <ul> <li>or install here: <a href="https://www.python.org/downloads/release/python-3100a6/">https://www.python.org/downloads/release/python-3100a6/</a></li> </ul></li> <li>Under Installing Alpha/Beta Version it has the steps to build from source. I strongly recommend replacing <code>make install</code> with <code>make altinstall</code>.</li> <li>Lots of comments and examples of pattern matching (aka switch).</li> <li>Type Checking Improvements</li> - </ul> <pre><code> # Function that accepts either `int` or `float` # Old: def func(value: Union[int, float]) -&gt; Union[int, float]: return value </code></pre> <pre><code> # New: def func(value: int | float) -&gt; int | float: return value </code></pre> <ul> <li>Type Aliases Syntax Change: <code>FileName = str</code> → <code>FileName: TypeAlias = str</code></li> <li>distutils Are Being Deprecated (deprecated in 3.10 and will be removed in 3.12). This package has been replaced by <code>setuptools</code> and <code>packaging</code> for a while now.</li> <li>Parenthesized context managers to span multiple lines</li> </ul> <pre><code> with ( open("somefile.txt") as some_file, open("otherfile.txt") as other_file, ): ... </code></pre> <p><strong>Gwen #6:</strong> <strong><a href="https://freecodecamp.com">freeCodeCamp’s Python Curriculum</a></strong></p> <ul> <li>Thousands of hours of Curriculum <ul> <li>Python basics</li> <li>Data Science</li> <li>Machine Learning</li> <li>Algorithms</li> <li>Projects</li> <li>Certifications</li> </ul></li> <li>YouTube supplementary material with 100s of hours of Python</li> <li>Quincy Larsen and the team worked on this for years and launched last year.</li> <li><a href="https://www.freecodecamp.org/news/building-a-data-science-curriculum-with-advanced-math-and-machine-learning/">New Data Science and ML curriculum</a> coming soon…</li> </ul> <p><strong>Extras</strong></p> <p><strong>Michael</strong></p> <ul> <li><a href="https://www.arnnet.com.au/article/687438/microsoft-unveils-its-own-java-distribution/"><strong>Microsoft unveils its own Java distribution</strong></a>: Microsoft Build of OpenJDK could set up the vendor to compete with Oracle in the Java distribution space, for Windows, Linux, and MacOS.</li> <li><a href="https://blog.jetbrains.com/pycharm/2021/04/pycharm-2021-1/"><strong>PyCharm 2021.1</strong></a></li> <li><a href="https://twitter.com/roman_the_right/status/1382344202839859201"><strong>Beanie ODM now has migrations</strong></a>!</li> </ul> <p><strong>Gwen</strong></p> <ul> <li><a href="https://mem.dev/">Mem.dev</a>: For developers to use spaced-repetition learning to learn concepts and syntax.</li> <li><a href="https://docs.graphene-python.org/projects/django/en/latest/">Graphene Django</a>: Testing it out to replace DRF for future development projects.</li> </ul>
Categories: FLOSS Project Planets

Pages