Feeds
Real Python: Mazes in Python Part 1: Building and Visualizing
If you’re up for a little challenge and would like to take your programming skills to the next level, then you’ve come to the right place! In this hands-on video course, you’ll practice object-oriented programming, among several other good practices, while building a cool maze solver project in Python.
This is the first part in a two-part series. Throughout the series, you’ll go step by step through the guided process of building a complete and working project. This will include reading a maze from a binary file, visualizing it using scalable vector graphics (SVG), and finding the shortest path from the entrance to the exit.
In part one of the series, you’ll learn how to:
- Use an object-oriented approach to represent the maze in memory
- Visualize the maze and its solution using scalable vector graphics (SVG)
In the next part of the series, you’ll complete the project by creating a binary storage format for mazes and solving mazes using NetworkX.
[ Improve Your Python With đ Python Tricks đ â Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
Mike Driscoll: Announcing The Python Show Podcast
The Python Show Podcast is something that I have thought about creating for several years. I have had several people tell me or ask me if I would do a podcast.
Of course, the problem with creating a podcast is choosing your niche. I donât want to sound like everyone else. On the other hand, my blog, Mouse vs Python, has been popular and different enough that many people from around the world have found it helpful.
So I decided that I was overthinking things. My passion has been and will continue to be around Python programming. It makes sense for my podcast to also be about Python.
Creating a Different PodcastThe main difference youâll find in my podcast is that I plan to do a mix of formats. Some episodes will be hosted solo. They will, in effect, be a monologue about whatever Python, tech, or content creation topic I want to talk about at that time.
Other episodes will feature one or more guests with Q&As , fireside-like chats, or a panel-type talk.
Whatâs Paid and Whatâs NotYouâll notice I have a paid tier for the podcast. The paid tier gives you access to the following:
- Video versions of the podcast (when applicable) before they appear on the YouTube channel
- Videos on this site will not have YouTube ads
- Behind-the-scenes articles and videos
- The highest quality version of the podcast (WAV files)
I am brand new at working with audio files, DAWs, etcetera. I expect the first few episodes will be a little rough around the edges, but as I gain experience, the future episodes will get more and more polished.
I hope youâll stick around and join me on this new adventure!
The post Announcing The Python Show Podcast appeared first on Mouse Vs Python.
Specbee: The Admin Toolbar - A Must-Have Drupal Module
WaitâŠhear us out first - imagine a scenario where you need to dig into your traditional closet to find that one dress to wear for a special occasion. Howâs the picture? Tiresome?
Now imagine a walk-in closet where you can quickly browse through all your outfits and hand-pick your favorite one for that special occasion.
The latter saves you time and gives you quick access to a variety of options. The Drupal Admin Toolbar module does the same for site admins. It makes your job easy and quick, gets you to your destination easily, and saves you a lot of time digging through your options on your website.
In this blog, youâll read about the benefits and uses of the Admin toolbar module. Youâre probably already using it, but if not, you will once you read this blog. Even if you are, read it anyway because weâll also talk about a few less-known facts about this module.
What is the Admin Toolbar Module?In the digital age, expecting things to get easier and easier with lesser human effort has become the norm. And this module is also an example of such ease of moderation.
The Admin Toolbar module is an upgrade to the standard or default toolbar, the administration menu at the top of your site. Using the module, you can empower the regular toolbar with drop-down menus and get quick access to all your admin pages.
This is a light module and can overwrite your default toolbar core module. It employs responsive shortcuts and keeps the default toolbar functionalities active.
Few Facts and Usage Stats of Drupal Admin Toolbar ModuleDid you know that the Drupal Admin Toolbar Module was released on April 20, 2015? And over time, its usage has kept growing consistently. Now, more than 280,000 websites have used this module.
Source: Drupal.org
Although this module is not yet in Drupal core, it could be a great feature to add to it. This way, it can further enhance usability out of the box.
Version Status and Sub-modulesVersion 3.x of this module has a configuration form so that site admins can limit the stock of bundles to be displayed in the drop-down menus.
Additionally, you can use the accompanied submodules as below:
Admin Toolbar Extra Tools: With this submodule, you can add a few menu items like Cache Rebuild, Run Cron, Index site, etc. which are frequently used admin tasks.
Admin Toolbar Search: You need this module to empower the search box to look for admin pages.
Admin Toolbar Links Access Filter: Using this submodule, you can filter out the links that shouldnât be accessible by users. Makes sure to use the route name instead of the internal path for custom menu links.
Benefits of the Admin Toolbar ModuleNot just the configuration form for this module, but Drupal has a comprehensive system that includes various configuration forms. Most of these configuration forms are nested and so, users can access them from the parent tab.
The default toolbar cannot lead you to your destination, as the administration menu is not expansive. It did take up oneâs time having to visit various websites for one particular action. In the previous scenario (before the launch of this module), you had to click on Content Type and then on Article to add an article.
Thanks to this module, you can now save a lot of time with drop-down lists with responsive, expanded functionalities. Additionally, you can restrict users from accessing certain links on our website. For this, you have the Admin Toolbar Access Filter, a submodule mentioned earlier.
How to install the Admin Toolbar module?Letâs start by downloading the Admin Toolbar module first.
1. Run this Composer command:
composer require drupal/admin_toolbar
2. Visit Extend page and click on Extend
Or visit: https://
3. Search for âadmin toolbarâ in the search box
4. Select the checkbox for Admin Toolbar
5. Install the Admin Toolbar module and its three submodules
Â
Â
The functionality of the toolbar depends on the collaboration of all four modules.
The Admin Toolbar Module and its 3 SubmodulesHere is a breakdown of all four modules that create the best output with collaboration:
Admin ToolbarIt is the base module and provides dropdown functionalities on your standard toolbar after installation.
Source: Drupal.org
As mentioned earlier, the 3.0.0 version of the module introduced a new configuration form which may have created performance issues. In order to configure this issue, go to:
Admin > Configuration > User interface > Admin Toolbar Tools
Make sure to take a hard look at the warning that says âLoading a large number of items can cause performance issues.â
Admin Toolbar Extra ToolsOne of the three submodules, the Admin Toolbar Extra Tools lets you add extra drop-down functionality via the following functions:
- Additional menu options in the dropdown functionality
- A Drupal logo in the top left corner of the Admin Toolbar
- A list of functioned indexed alphabetically
- Flush individual or all caches
- Need not wait for 3 hours, instead run cron job immediately
- Post module updates, run a system updateÂ
- Employ quick access to logout function
Site admins can restrict users from accessing specific links. These users will have âUse the Administration Pages and Helpâ permission but no access to certain pages on the website. However, such users can still view the menu items. This submodule can be used simply by installing it and does not require any configuration.
Admin Toolbar SearchYou will find the Admin Toolbar Search box on the Admin Toolbar itself. Beginners, site builders, or admins new to Drupal can use this search box to look for functions or administrative and configuration pages.
Complementary ModulesThese are a few sub-modules to add the cherry topping to the cake you made with the Admin Toolbar module -Â
- Toolbar Menu: Add any menu that easily blends with the Admin toolbar, making them easily accessible dropdown menus.
- Toolbar Anti-flicker: Remove any impact of the toolbar submenus on the rest of your website page.
- Coffee: Look for admin paths with this module.
- Adminimal Admin Toolbar: Add a black theme to your page.
- Admin Toolbar Content Language: Add links to create content using any active language.
- Toolbar Themes: Access great UI themes from here.
If you want a list of must-have Drupal modules for your website, the Admin Toolbar module is one to include in that list. Site admins and builders can easily manage content and configure and develop a better user experience.
Reference:
- https://www.droptica.com/blog/how-manage-backend-website-drupal-admin-toolbar-module/Â
- https://www.volacci.com/drupal-seo-guide/drupal-admin-toolbar-moduleÂ
- https://www.webwash.net/quick-search-and-drop-downs-to-toolbar-using-admin-toolbar-in-drupal/Â
- https://www.drupal.org/project/admin_toolbar
Author: Priyanka Phukan
Meet Priyanka, a Junior Content Writer and Marketer at Specbee. Priyankaâs a Grammar-Freak with a knack for creating impactful content with âwordsâ being her weapon of choice. A foodie who likes all things chicken. When not writing, she likes to play the Uke and sing. On blue days, youâll find her binge-watching Asian dramas.
Email Address Subscribe Leave this field blank Drupal Drupal Module Drupal Development Drupal PlanetLeave us a Comment
 Recent Blogs Image The Admin Toolbar - A Must-Have Drupal Module Image Understanding Update and Post Update Hooks for Successful Drupal Site Updates Image How to Adhere to Drupal Coding Standards with Git Hooks Want to extract the maximum out of Drupal? TALK TO US Featured Case StudiesUpgrading the web presence of IEEE Information Theory Society, the most trusted voice for advanced technology
ExploreA Drupal powered multi-site, multi-lingual platform to enable a unified user experience at SEMI
ExploreGreat Southern Homes, one of the fastest growing home builders in the US, sees greater results with Drupal
Explore View all Case StudiesRussell Coker: PinePhonePro First Impression
I received my PinePhone Pro [1] on Thursday, it seems in many ways better than the Purism Librem 5 [2] that I have previously written about. The PinePhone is thinner, lighter, and yet has a much longer battery life. A friend described the Librem5 as âthe CyberTruck phoneâ and not in a good way.
In a test I had my PinePhone and my Librem5 fully charged, left them for 4.5 hours without doing anything much with them, and then the PinePhone was at 85% and the Librem5 was at 57%. So the Librem5 will run out of battery after about 10 hours of not being used while a PinePhonePro can be expected to last about 30 hours. The PinePhonePro isnât as good as some of the recent Android phones in this regard but it shows the potential to be quite usable. For this test both phones were connected to a 2.4GHz Wifi network (which uses less power than 5GHz) and doing nothing much with an out of the box configuration. A phone that is checking email, social networking, and a couple of IM services will use the battery faster. But even if the PinePhone has itâs battery used twice as fast in a more realistic test that will still be usable.
Here are the passmark results from the PinePhone Pro [3] which got a CPU score of 888 compared to 507 for the Librem 5 and 678 for one of the slower laptops Iâve used. The results are excluded from the Passmark averages because they identified the CPU as only having 4 cores (expecting just 4*A72) while the PinePhonePro has 6 cores (2*A72+4*A53). This phone definitely has the CPU power for convergence [4]!
Default OSBy default the PinePhone has a KDE based GUI and the Librem5 has a GNOME based GUI. I donât like any iteration of GNOME (I have tried them all and disliked them all) and I like KDE so I will tend to like anything that is KDE based more than anything GNOME based. But in addition to that the PinePhone has an interface that looks a lot like Android with the three on-screen buttons at the bottom of the display and the way it has the slide up tray for installed apps. Android is the most popular phone OS and looking like the most common option is often a good idea for a new and different product, this seems like an objective criteria to determine that the default GUI on the PinePhone is a better choice (at least for the default).
When I first booted it and connected it to Wifi the updates app said that there were 633 updates to apply, but never applied them (I tried clicking on the update button but to no avail) and didnât give any error message. For me not being Debian is enough reason to dislike Manjaro, but if that wasnât enough then the failure to update would be a good start. When I ran pacman in a terminal window it said that each package was corrupt and asked if I wanted to delete it. According to âtar tvJfâ the packages werenât corrupt. After downloading them again it said that they were corrupt again so it seemed that pacman wasnât working correctly.
When the screen is locked and a call comes in it gives a window with Accept and Reject buttons but neither of them works. The default country code for âSpacebarâ (the SMS app) is +1 (US) even though I specified Australia on the initial login. It also doesnât get the APN unlike Android phones which seem to have some sort of list of APNs.
Upgrading to DebianThe Debian Wiki page about Installing on the PinePhone Pro has the basic information [5]. The first thing it covers is installing the TOW boot loader â which is already installed by default in recent PinePhones (such as mine). You can recognise that TOW is installed by pressing the volume-up button in the early stages of boot up (described as âbefore and during the second vibrationâ), then the LED will turn blue and the phone will act as a USB mass storage device which makes it easy to do other install/recovery tasks. The other TOW option is to press volume-down to boot from a MicroSD card (the default is to boot the OS on the eMMC).
The images linked from the Debian wiki page are designed to be installed with bmaptool from the bmap-tools Debian package. After installing that package and downloading the pre-built Mobian image I installed it with the command âbmaptool copy mobian-pinephonepro-phosh-bookworm-12.0-rc3.img.gz /dev/sdbâ where /dev/sdb is the device that the USB mapped PinePhone storage was located. That took 6 minutes and then I rebooted my PinePhone into Mobian!
Unfortunately the default GUI for Mobian is GNOME/Phosh. Changing it to KDE is my next task.
- [1] https://www.pine64.org/pinephonepro/
- [2] https://etbe.coker.com.au/2022/03/19/more-librem5/
- [3] https://tinyurl.com/2pspc8jt
- [4] https://etbe.coker.com.au/2023/05/29/considering-convergence/
- [5] https://wiki.debian.org/InstallingDebianOn/PINE64/PinePhonePro
Related posts:
- More About the Librem 5 I concluded my previous post about the Purism Librem 5...
- Librem 5 First Impression I just received the Purism Librem 5 that I paid...
- Considering Convergence What is Convergence In 2013 Kyle Rankin (at the time...
The Drop Times: Five Spots to Visit in Pittsburgh: Suggestions from an Amateur Tourist
Consensus Enterprises: Aegir5: Feature parity between Aegir3 and Aegir5
Acquia.com - Drupal Blog: Acquia to Support Drupal 7 Through 2025
Stack Abuse: Finding Numbers in Various Data Types in Python
When working with Python, we often have to deal with data in the form of numbers or words. Sometimes, words and numbers are stored together, and our needs compel us to separate numbers from words.
In this article, we'll explain how to define words and numbers in Python. Then, we'll see how to separate numbers from words, in case they're stored together, using different methods and in various situations.
Strings, Integers, and Floats in PythonIn Python, strings, integers, and floats are fundamental data types used to represent different kinds of values in a program.
Integers represent whole numbers without any decimal part and can be positive or negative. Here's how to define an integer in Python:
# Create a variable expressing an integer number age = 15We've created a variable called age and assigned it the value of 15. To verify the type of a variable in Python, we can use the built-in function type(). This is how it works:
# Show the type type(age)And we get:
intSo, we pass the variable age to the built-in function type() and it tells us that this is an integer, as we expected.
To express numbers, we can also use the float type. A float, which is short for floating-point numbers, represents real numbers with decimal points. They are generally suitable for scientific calculations, but not only. Here's how we define a float in Python:
# Create a variable expressing a float number pi = 3.14And again, to check the type of our variable:
# Show the type type(pi)And we get:
floatStrings are a sequence of characters enclosed in double quotes or single quotes. They are used to store text or, more generally, any kind of characters. This means that a string can even contain numbers, which is the focus of this article. So, for example, a string can be:
# Create a string with my name my_name = "Federico" # Show the type type(my_name)And we get:
strBut it can also be:
# Create a variable with text and number federico_car = 'Federico has 1 car'Finally, pay attention: we said that a string in Python is any character enclosed in quotes. This means that the type of the following:
# Create a string variable expressing a number age = '15'is str.
Now, with this overview in mind, let's see some methods to intercept numbers inside strings.
Methods to Find Numbers in StringsLet's see an overview of some methods we can use to check if a string contains numbers.
The int() and float() MethodsThe easiest ways to transform a string into a number are through the int() and float() methods. Let's see how we can use them.
Suppose we expressed our age as a string, but we want it as an integer. We can do it like so:
# Create a string variable expressing an integer number age = '30' # Transform string into integer type age_int = int(age) # Show type type(age_int)And we have:
intSo, we've defined the variable age as a string. Then, we passed it as the argument of the method int() and it transformed the string into an integer.
Now, suppose we have expressed a price as a string, but we want to convert it to a float. We can do it like so:
# Create a string variable expressing a decimal number price = "34.99" # Transform string to float type price_float = float(price) # Show type type(price_float)And we have:
floatSimilarly, as before, we pass a string to the method float() and it transforms it into a float.
Now, these methods are easy to use but have a significant limitation: they can convert strings into numbers only if the value inside the quotes is a number. So, to get an understanding, consider the following example:
# Create a string with text and numbers apples = "21 apples" # Transform string to integer apples_converted = int(apples) # Show type type(apples_converted)And we get:
ValueError: invalid literal for int() with base 10: '21 apples'This error means that we're trying to convert a string to an integer, but the string cannot be parsed as a valid integer. Of course, the same issue occurs if we parse a string containing only text or if we use the float() method.
Now, a question may arise: what if the text in the string expresses an integer and we want to convert it to a float? And how about vice-versa? Let's examine both scenarios:
# Create a string expressing a decimal price = "30.5" # Transform string into an integer price_int = int(price) # Show type type(price_int)And we get:
ValueError: invalid literal for int() with base 10So, we have expressed the price of an object as a decimal number (although the type is a string!) and tried to convert it into an integer. This is not possible, as the error indicates.
Now, let's see the other case:
# Create a string expressing an integer price = "30" # Transform string into a float price_float = float(price) # Show type type(price_float)And we get:
floatSo, we can convert a string that expresses a whole number into a float. In fact, if we want to see how Python expresses this number as a float, we can print it:
# Print transformed variable print(price_float)And, as we might expect, we get:
30.0Now, these two methods are very basic and have some limitations, as we've seen. This is why we need to learn other methods to solve our problem in more general situations.
The isdigit() MethodThe isdigit() method checks if all the characters in a string are digits (0-9). It returns True if the string contains only digits, and False otherwise. So, let's see a couple of examples:
# Create string with text and numbers letters_and_numbers = "Hello123" # Create string with only text letters = "Hello World" # Create string with only numbers numbers = "123456"Now, let's use the isdigit() method:
# Apply isdigit() method and print print(letters_and_numbers.isdigit()) print(letters.isdigit()) print(numbers.isdigit())And we get:
False False TrueSo, to use this method, we write the name of the variable we're verifying and we add .isdigit(). As we expected, the results show that only the variable numbers contains characters that are all digits.
This method is good, but we can do better in Python. Listing all the printed values, in fact, may become difficult to read. So, we can improve the above code like so:
# Apply isdigit() method and print, showing variables and results print(f"Is {letters_and_numbers} an only digit string? {letters_and_numbers.isdigit()}") print(f"Is {letters} an only digit string? {letters.isdigit()}") print(f"Is {numbers} an only digit string? {numbers.isdigit()}")And we get:
Is Hello123 an only digit string? False Is Hello World an only digit string? False Is 123456 an only digit string? TrueSo, inside print(), we can use f before the double quotes to insert the variables inside the curly brackets {}. This allows Python to return the actual value of the variable passed through the curly brackets. Then, knowing that the isdigit() method returns a boolean (True or False), the above code provides more readable results.
Now, it would be beneficial if this method could detect numbers in strings containing both digits and other characters. To achieve this, we can create a function like so:
# Create a function that detects digits in strings def contains_number(string: str) -> bool: return any(char.isdigit() for char in string)Next, we pass the letters_and_numbers variable to the contains_number() function and observe the result:
# Invoke the function, passing 'letters_and_numbers' as an argument contains_number(letters_and_numbers)And we get:
TrueExactly as we wanted: We were able to intercept digits in a variable that contains different kinds of characters. Now, let's explain this function step by step:
-
def contains_number(string: str) -> bool means that we are defining a function called contains_number() where we expect the argument, which we generically called string, to be a string (:str). Then, we know that the function will return a boolean (->bool). Note that this notation, called "Type Hints", is available from Python 3 onwards, and it is not mandatory. We could have written def contains_number(string): and the function would work correctly. Type Hints are just a useful way to inform the user on what types to expect when dealing with functions (and classes), so it's a kind of "a facilitator".
-
Now, let's explain any(char.isdigit() for char in string) which is what the function returns. First, we have created a generator expression (a generator is a special type of object in Python that allows us to generate a sequence of values dynamically, without needing to store all the values in memory at once) with char.isdigit() for char in string. This generates a sequence of Boolean values, indicating whether each character in the string is a digit. In particular, for char in string iterates over each character char in the argument string, passed to the function. Then, char.isdigit() checks if the character char is a digit. Finally, the any() function is a built-in Python function that takes an iterable as an argument and returns True if at least one element in the iterable is True. It returns False if all elements are False. So, in conclusion, any(char.isdigit() for char in string) evaluates to True if at least one character in the string is a digit, and False otherwise.
Now, let's see other methods.
Using Regular ExpressionsAnother method we can use to find if a string contains a number is through regular expressions (also called "regex"). Regular expressions are a sequence of characters that help us match or find patterns in text. Here's how we can use this Python module for our purposes:
import re # Create strings letters_and_numbers = "Hello123 0.3" letters = "Hello World" numbers = "1 2 3 4 5 6 0.5" # Use regex to intercept numbers and print results print(bool(re.search(r'\d', letters_and_numbers))) print(bool(re.search(r'\d', letters))) print(bool(re.search(r'\d', numbers)))And we get:
True False TrueSo, first we need to import the re module to use regular expressions. Then, we can use the re.search() method for each variable to check for any digits. In regular expressions, \d represents any digit character. Next, we apply the bool() method, which returns a boolean value. If there are any digits in the string we are checking, we get True.
Note that, compared to the previous method, this one identifies numbers without using a function. This method also detects the decimal number in the string letters_and_numbers, unlike the previous method that only detects digits (numbers from 0 to 9). We'll explain more about this in the next paragraph.
Now, let's examine the last method.
The isnumeric() MethodThe isnumeric() method works exactly like the isdigit() method: it returns True if all characters in the string are numbers. The difference between the two is that isnumeric() can identify a wider range of numbers, such as floats, fractions, superscripts, subscripts, and more. So, if we're aware we're searching for numbers that can be in different forms, then isnumeric() should be preferred.
On the coding side, we use it similarly to the isdigit() method. Let's see a simple example:
# Create strings letters_and_numbers = "Hello123" letters = "Hello World" numbers = "1 2 3 4 5 6 0.5" # Apply isnumeric() method and print results print(letters_and_numbers.isnumeric()) print(letters.isnumeric()) print(numbers.isnumeric())And we get:
False False TrueNow, let's see some more advanced examples we may encounter while programming in Python.
Advanced Manipulation ExamplesNow we want to show how we can use the methods we've seen above to intercept numbers in strings in more practical situations, for example when analyzing lists, dictionaries, and data frames.
Finding Numbers in Strings in ListsConsider we have a list where we have stored some strings containing both numbers and text. We could extract the numbers with regular expressions like so:
import re # Create a list with strings expressing text and numbers data = ['I have 10 apples', 'There are 5 bananas', 'I will buy one apple'] # Create a function to retrieve numbers in strings def extract_numbers(string): return re.findall(r'\d+', string) # Iterate over the list, extract numbers, and print results for string in data: numbers = extract_numbers(string) print(f"Numbers in string: {string} - {numbers}")And we get:
Numbers in string: I have 10 apples - ['10'] Numbers in string: There are 5 bananas - ['5'] Numbers in string: I will buy one apple - []So, here we report the number associated with the string, if present. The only differences between the previous example on regular expressions are:
- We used re.findall(). This method takes two arguments: pattern and string. It searches for all occurrences of the pattern within the string and returns a list of all matched substrings.
- In this case, the pattern is represented by \d+, which matches one or more consecutive digits in the string using regex.
So, we have stored numbers and text in some strings in a list called data. We have created a function called extract_numbers() that intercepts all the consecutive digits in the string through the method re.findall(), thanks to regex. We then iterate through the list with a for loop and invoke the function extract_numbers() so that all the strings in the list are checked. Then, the code prints the strings themselves and the numbers intercepted (if any).
Finding Numbers in Strings in DictionariesNow, suppose we have a shopping list stored in a dictionary where we report some fruit and their respective prices. We want to see if the price is expressed as a number. We can do it like so:
# Create function to intercept numbers in strings def contains_number(string: str) -> bool: return any(char.isnumeric() for char in string) # Create a dictionary shopping_list = { 'Banana': '1', 'Apple': 'Five', 'Strawberry': '3.5', 'Pear': '3', } # Iterate over dictionary and print results for key, value in shopping_list.items(): if contains_number(value): print(f"Value for '{key}' contains a number: {value}") else: print(f"Value for '{key}' does not contain a number: {value}")And we get:
Value for 'Banana' contains a number: 1 Value for 'Apple' does not contain a number: Five Value for 'Strawberry' contains a number: 3.5 Value for 'Pear' contains a number: 3So, we have created a function contains_number() as we have seen before, but here we've used the isnumeric() method (we have a decimal). We then store the prices of some fruits in a dictionary called shopping_list. With shopping_list.items(), we access the keys and values of the dictionary, and check if the values are numeric by invoking the function contains_number(). Finally, thanks to an if statement, we can separate the strings containing numbers from those containing only text, and print the results.
Finding Numbers in Strings in Pandas Data FramesIn Python, we can store data in data frames, which are collections of columns and rows (similar to Excel sheets, for simplicity). Data frames can be manipulated with a library called pandas in Python.
Suppose we want to create a column (we call a single column of a data frame a "Pandas series") where we have stored the price of an object from different suppliers on Amazon:
import pandas as pd # Create dictionary data = {'Amazon_prices': ['10', '8', '9.2', 'eleven', 'seven']} # Transform dictionary into data frame df = pd.DataFrame(data) # Print data frame print(df)And we have:
Amazon_prices 0 10 1 8 2 9.2 3 eleven 4 sevenSo, we have stored some data in a dictionary called data. Then, with the pd.DataFrame() method, we've converted the dictionary into a Pandas data frame called df.
At this point, we can use the str.contains() method from the Pandas library, which is useful for checking patterns in strings. We can use regex to define the pattern like so:
# Intercept numbers in column numeric_values = df['Amazon_prices'].str.contains(r'\d+', regex=True)With the above code, we are checking if the column Amazon_prices contains numbers, thanks to regex. With df['Amazon_prices'], we are selecting the column of the data frame. Then, the .str.contains() method checks if we have at least one number in the strings, thanks to regex, as seen before. Finally, the regex=True activates the use of regex.
We can then create a new column to add to our data frame with the resulting booleans like so:
# Create a new column for data frame df['IsNumeric'] = numeric_valuesSo, IsNumeric is the new column of our data frame, containing the booleans. We can now print the modified data frame with print(df) and we get:
Amazon_prices IsNumeric 0 10 True 1 8 True 2 9.2 True 3 eleven False 4 seven FalseAnd then, we have a complete overview of the data frame.
ConclusionsIn this article, we've seen various methods to determine if there are any numbers in strings, in different cases and situations. We've also demonstrated that there is no one-size-fits-all method; depending on the situation, we have to choose the one that best suits the specific problem we're facing.
Drupal Core News: Lauri to become a Drupal Core Product Manager
I am happy to share that Lauri Eskola has accepted our invitation to become a Drupal Core Product Manager.
The Core Product Managers communicate with different types of users, gather data about how Drupal is currently being used, and represent Drupal's end users (like site builders and content authors). They help determine the core feature set and work to holistically improve Drupal's out-of-the-box experience.
Lauri has been working with Drupal for almost 13 years. Not only is Lauri a subsystem maintainer of the theme system, Claro, and CKEditor 5, but he has also been a Frontend Framework Manager and a Drupal Core Committer since 2017.
Throughout the years, Lauri's enthusiasm for driving user-facing improvements has grown. In light of this, we have decided to transition Lauri's role from being a Drupal Core Frontend Framework Manager to becoming a Product Manager.
Lauri is looking forward to helping the project by prioritizing and supporting efforts to make Drupal an even more powerful tool for ambitious site builders.
LN Webworks: Proprietary vs. Open-Source Platforms: Debunking 3 Common Myths
You must be caught up in the debate between proprietary and open-source platforms. This debate has captivated the minds of industry leaders and enthusiasts alike while sparking confusion and hindering informed decision-making. But letâs face it: Thereâs a lot of misinformation floating around.
Choosing the right platform becomes even more important in this fast-moving digital landscape, as it can impact everything from innovation to security and cost. Uncover the truth through this article as it dispels the top three myths about proprietary and open-source platforms, empowering you to make a well-informed decision for your organization's progress.
The Drop Times: DrupalCon Pittsburgh: Dries's Inspiring Keynote Address Is the First Day's Major Takeaway
Russell Coker: Dell 32âł 4K Monitor and DisplayPort Switch
After determining that the Philips 43âł monitor was too large for my taste as well as not having a clear enough display [1] I bought a Dell 32âł 4K monitor for $499 on the 1st of July 2022. That monitor has been working nicely for almost a year now, for DisplayPort itâs operation is perfect and 32âł seems like an ideal size for my use. There is one problem that both HDMI ports will sometimes turn off for about half a second, Iâve tested on both ports and on multiple computers as well as a dock and it gives the same result so itâs definitely the monitor. The problem for me is that the most casual inspection wonât reveal the problem and the monitor is large and difficult to transport as Iâve thrown out the box. If I had this sort of problem with a monitor at work Iâd add it to the list of things for Dell to fix next time they visit the office or use one of the many monitor boxes available to ship it back to them. But for home use itâs more of a problem for me. The easiest solution is to avoid HDMI.
A year ago I blogged about using DDC to switch monitor inputs [2], I had that running with a cheap USB switch since then to allow a workstation and a laptop to share the same monitor, keyboard, and mouse. Recently I got a USB-C dock that allows a USB-C laptop to talk to a display via DisplayPort as opposed to the HDMI connector thatâs built in. But my Dell monitor only has one DisplayPort input.
So I have just bought a DisplayPort and USB KVM switch via eBay for $52, a reasonable price given that last year such things were well over $100. It has ports for 3 USB devices which is better than my previous setup of a USB switch with only a single port that I used with a 3 port hub for my keyboard and mouse.
the DisplayPort switch is described as doing 4K at 60Hz, I donât know how it will perform with a 5K monitor, maybe it will work at 30Hz or 40Hz. But currently Dell 5K monitors are at $2,500 and 6K monitors are about $3,800 so I donât plan to get one of them any time soon.
- [1] https://etbe.coker.com.au/2022/06/29/philips-438p1-43-4k/
- [2] https://etbe.coker.com.au/2022/07/19/ddc-switch/
Related posts:
- Philips 438P1 43âł 4K Monitor I have just returned a Philips 438P1 43âł 4K Monitor...
- DisplayPort and 4K The Problem Video playback looks better with a higher scan...
- DDC as a KVM Switch With the recent resurgence in Covid19 Iâve been working from...
Object Lifetime
Last time we discussed Value Semantics. However, I missed one topic that is super important for a better understanding of basic building blocks of C++. Today, we are going to talk about an object. Without further ado, letâs dive deeper!
ObjectWhat is an object? According to the C++ standard, part 3.9.8 under the name of [basic.types]
An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not a void type.Now is int i an object? Yes.
Is void* p an object? Still yes, because pointers are types themselves, they are not references.
As we said, references are not types, but what if we declare something like struct S{ int& ref;};Â would that be an object type? Put your answers down below, I’d like to see your opinion on this. đ
LifetimeWhen we talk about objects, the one idea that always follows is lifetime.
Lifetime is a period in which an object is fully initialized. It begins with
- storage with the proper alignment,
- obtaining size for type T, and
- if the object has non-trivial initialization, its initialization is complete.
The lifetime of an object of type T ends when:
- T is a class type with a non-trivial destructor,
- the destructor call starts, or
- the storage which the object occupies is reused or released
This is an extraction from [basic.life] paragraph of C++ standard. In easy words, complex objects live from the end of the constructor, until the beginning of a destructor, and the trivial objects, like int live from their storage allocation, until the end of the scope. Seems pretty easy, right?
So, if you see something like:
auto& GetData(){ const int i = 5; return i; }you’d probably say that there is something fishy about it, and you’d be correct. Although i is returned from a function, notice the auto& here. It says that we’re actually returning a reference to a local variable. After the function returns, the stack is cleaned. Hence, you invoke a good old UB.
But what if we change the function to return a string instead of an int?
auto* GetData(){ const char* i = "Hello"; return i; }Now we get a normal “Hello” string from a function. This is due to a simple rule of a language, that states that all strings are valid throughout the entire program because they have a static storage.
But let’s change the story again:
auto* GetData(){ const char[] i = "Hello"; return i; }Notice that I’ve changed only one character and suddenly everything breaks. The behavior is undefined, everything crashes and burns. What happened here? We actually initialized the array with a copy of static data and returned a pointer to it.
Strings live longer, than you think they will, except when they don’t – Jason Turner @ CppCon 2018
Complex objects and their lifetimesAs we already discussed, lifetime of a complex object begins with a constructor and ends with a destructor. Although there are objects that have implicit destructors and constructors, there still may be things that may surprise you.
Firstly, the lifetime begins with the ending of the constructor execution.
That means a lot. Let’s have a look at an example:
struct S { S(){} ~S(){} }; int main(){S s;}I think everyone will agree that the call order is constructor, and then destructor. But what if I present exceptions to the equation? What if S() may throw?
Well, the answer is: the destructor does not start! Why? Because the lifetime of an object did not start, since the constructor didn’t finish its execution.
Here lies a menace:
struct S { S(int a){ a = new MyWidgetNothrow(a); b = new MyWidgetThrows(a); } ~S(){ delete a; delete b; } MyWidget* a; MyWidget* b; }; int main(){S s;}Are widgets deleted with the unwinding if the second object throws? No, the memory will leak. Hence, this is why the usage of new operator is a bad code smell and we should avoid it whenever possible. Here is an example on Godbolt.
However, a good thing to mention is that the stack unwinder actually destroys all initialized objects from within the class on throw. So, the pointer being an object type is trivially destroyed, but not the memory behind it.
What can we do to make this code work? Delegating constructors comes into play!
struct S { S() = default; S(int a):S{} { a = new MyWidgetNothrow; b = new MyWidgetThrows; } ~S(){ delete a; delete b; } MyWidget* a = nullptr; MyWidget* b = nullptr; }; int main(){S s;}Here, the delegation constructor finished its execution, hence the object is alive, and the destructor finishes successfully on throw. This information brings us to the point of smart pointers. Since in many cases you can’t have an additional constructor to delegate to, or even a constructor at all, you need smart pointers to have robust code and ensure correct ownership of the objects.
ConclusionToday we have touched a very basic yet complex topic of object lifetimes. Of course, there is a lot more to say and we will continue basics in the next post tackling move semantics with lifetime implications and finishing with a sprinkle of ownership semantics of smart pointers.
I hope you enjoyed the read. There is a plan for a video series that tackles modern C++ 20/23 topics and use the concepts in practice. Stay tuned for the announcement. đ
Be careful when returning references and wrapper objects from a function, and use new as rarely as possible! Enjoy object lifetime!
Sincerely,
Ilya “Agrael” Doroshenko
About KDAB
If you like this article and want to read similar material, 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 Object Lifetime appeared first on KDAB.
Shirish Agarwal: Odisha Train Crash and Coverup, Demonetization 2.0 & NHFS-6 Survey
Just a few days back we came to know about the horrific Train Crash that happened in Odisha (Orissa). There are some things that are known and somethings that can be inferred by observance. Sadly, it seems the incident is going to be covered up . Some of the facts that have not been contested in the public domain are that there were three lines. One loop line on which the Goods Train was standing and there was an up and a down line. So three lines were there. Apparently, the signalling system and the inter-locking system had issues as highlighted by an official about a month back. That letter, thankfully is in the public domain and I have downloaded it as well. Itâs a letter that goes to 4 pages. The RW is incensed that the letter got leaked and is in public domain. They are blaming everyone and espousing conspiracy theories rather than taking the minister to task. Incidentally, the Minister has three ministries that he currently holds. Ministry of Communication, Ministry of Electronics and Information Technology (MEIT), and Railways Ministry. Each Ministry in itself is important and has revenues of more than 6 lakh crore rupees. How he is able to do justice to all the three ministries is beyond me
The other thing is funds both for safety and relaying of tracks has been either not sanctioned or unutilized. In fact, CAG and the Railway Brass had shared how derailments have increased and unfulfilled vacancies but they were given no importance In fact, not talking about safety in the recently held âChintan Shivirâ (brainstorming session) tells you how much the Govt. is serious about safety. In fact, most of the programme was on high speed rail which is a white elephant. I have shared a whitepaper done by RW in the U.S. that tells how high-speed rail doesnât make economic sense. And that is an economy that is 20 times + the Indian Economy. Even the Chinese are stopping with HSR as it doesnât make economic sense.
Incidentally, Air Fares again went up 200% yesterday. Somebody shared in the region of 20k + for an Air ticket from their place to Bangalore
Coming back to the story itself. the Goods Train was on the loopline. Some say it was a little bit on the outer, some say otherwise, but it is established that it was on the loopline. This is standard behavior on and around Railway Stations around the world. Whether it was in the Inner or Outer doesnât make much of a difference with what happened next. The first train that collided with the goods train was the 12864 (SMVB-HWH) Yashwantpur Howrah Express and got derailed on to the next track where from the opposite direction 12841 (Shalimar- Bangalore) Coramandel Express was coming. Now they have said that around 300 people have died and that seems to be part of the cover-up. Both the trains are long trains, having between 23 odd coaches each. Even if you have reserved tickets you have 80 odd people in a coach and usually in most of these trains, it is at least double of that. Lot of money goes to TC and then above (Corruption). The Railway fares have gone up enormously but thatâs a question for perhaps another time . So at the very least, we could be looking at more than 1000 people having died. The numbers are being under-reported so that nobody has to take responsibility. The Railways itself has told that it is unable to identify 80% of the people who have died. This means that 80% were unreserved ticket holders or a majority of them. There have been disturbing images as how bodies have been flung over on tractors and whatnot to be either buried or cremated without a thought. We are in peak summer season so bodies will start to rot within 24-48 hours No arrangements made to cool the bodies and take some information and identifying marks or whatever. The whole thing being done in a very callous manner, not giving dignity to even those who have died for no fault of their own. The dissent note also tells that a cover-up is also in the picture. Apparently, India doesnât have nor does it feel to have a need for something like the NTSB that the U.S. used when it hauled both the plane manufacturer (Boeing) and the FAA when the 737 Max went down due to improper data collection and sharing of data with pilots. And with no accountability being fixed to Minister or any of the senior staff, a small junior staff person may be fired. Perhaps the same official that actually told them about the signal failures almost 3 months back
There were and are also some reports that some âjugaaduâ/temporary fixes were applied to signalling and inter-locking just before this incident happened. I do not know nor confirm one way or the other if the above happened. I can however point out that if such a thing happened, then usually a traffic block is announced and all traffic on those lines are stopped. This has been the thing I know for decades. Traveling between Mumbai and Pune multiple times over the years am aware about traffic block. If some repair work was going on and it wasnât able to complete the work within the time-frame then that may well have contributed to the accident. There is also a bit muddying of the waters where it is being said that one of the trains was 4 hours late, which one is conflicting stories.
On top of the whole thing, they have put the case to be investigated by CBI and hinting at sabotage. They also tried to paint a religious structure as mosque, later turned out to be a temple. The RW says done by Muslims as it was Friday not taking into account as shared before that most Railway maintenance works are usually done between Friday â Monday. This is a practice followed not just in India but world over.
There has been also move over a decade to remove wooden sleepers and have concrete sleepers. Unlike the wooden ones they do not expand and contract as much and their life is much more longer than the wooden ones. Funds had been marked (although lower than last few years) but not yet spent. As we know in case of any accident, it is when all the holes in cheese line up it happens. Fukushima is a great example of that, no sea wall even though Japan is no stranger to Tsunamis. External power at the same level as the plant. (10 meters above sea-level), no training for cascading failures scenarios which is what happened. The Days mini-series shares some but not all the faults that happened at Fukushima and the Govt. response to it. There is a difference though, the Japanese Prime Minister resigned on moral grounds. Here, nor the PM, nor the Minister would be resigning on moral grounds or otherwise :(. Zero accountability and that was partly a natural disaster, here itâs man-made. In fact, both the Minister and the Prime Minister arrived with their entourages, did a PR blitzkrieg showing how concerned they are. Within 50 hours, the lines were cleared. The part-time Railway Minister shared that he knows the root cause and then few hours later has given the case to CBI. All are saying, wait for the inquiry report. To date, none of the accidents even in this Govt. has produced an investigation report. And even if it did, I am sure it will whitewash as it did in case of Adani as I had shared before in the previous blog post. Incidentally, it is reported that Adani paid off some of its debt, but when questioned as to where they got the money, complete silence on that part :(. As can be seen cover-up after cover-up
FWIW, the Coramandel Express is known as the Migrant train so has a huge number of passengers, the other one which was collided with is known as âsick trainâ as huge number of cancer patients use it to travel to Chennai and come back
Demonetization 2.0Few days back, India announced demonetization 2.0. Surprised, donât be. Apparently, INR 2k/- is being used for corruption and Mr. Modi is unhappy about it. He actually didnât like the INR 2k/- note but was told that it was needed, who told him we are unaware to date. At that time the RBI Governor was Mr. Urjit Patel who didnât say about INR 2k/- he had said that INR 1k/- note redesigned would come in the market. That has yet to happen. What has happened is that just like INR 500/- and INR 1k/- note is concerned, RBI will no longer honor the INR 2k/- note. Obviously, this has made our neighbors angry, namely Nepal, Sri Lanka, Bhutan etc. who do some trading with us. 2 Deccan herald columns share the limelight on it. Apparently, India wants to be the worldâs currency reserve but doesnât want to play by the rules for everyone else. It was pointed out that both the U.S. and Singapore had retired their currencies but they will honor that promise even today. The Singapore example being a bit closer (as itâs in Asia) is perhaps a bit more relevant than the U.S. one. Singapore retired the SGD $10,000 as of 2014 but even in 2022, it remains as legal tender. They also retired the SGD $1,000 in 2020 but still remains legal tender.
So letâs have a fictitious example to illustrate what is meant by what Singapore has done. Letâs say I go to Singapore, rent a flat, and find a $1000 note in that house somewhere. Both practically and theoretically, I could go down to any of the banks, get the amount transferred to my wallet, bank account etc. and nobody will question. Because they have promised the same. Interestingly, the Singapore Dollar has been pretty resilient against the USD for quite a number of years vis-a-vis other Asian currencies.
Most of the INR 2k/- notes were also found and exchanged in Gujarat in just a few days (The PM and HMâs state.). I am sure you are looking into the mental gymnastics that the RW indulge in :(. What is sadder that most of the people who try to defend canât make sense one way or the other and start to name-call and get personal as they have nothing else
Disability questions dropped in NHFS-6Just came to know today that in the upcoming National Family Health Survey-6 disability questions are being dropped. Why is this important. To put it simply, if you donât have numbers, you wonât and canât make policies for them. India is one of the worst countries to live if you are disabled. The easiest way to share to draw attention is most Railway platforms are not at level with people. Just as Mick Lynch shares in the UK, the same is pretty much true for India too. Meanwhile in Europe, they do make an effort to be level so even disabled people have some dignity. If your public transport is sorted, then people would want much more and you will be obligated to provide for them as they are citizens. Here, we have had many reports of women being sexually molested when being transferred from platform to coach irrespective of their age or whatnot The main takeaway is if you do not have their voice, you wonât make policies for them. They wonât go away but you will make life hell for them. One thing to keep in mind that most people assume that most people are disabled from birth. This may or may not be true. For e.g. in the above triple Railways accidents, there are bound to be disabled people or newly disabled people who were healthy before the accident. The most common accident is road accidents, some involving pedestrians and vehicles or both, the easiest is Ministry of Road Transport data that says 4,00,000 people sustained injuries in 2021 alone in road mishaps. And this is in a country where even accidents are highly under-reported, for more than one reason. The biggest reason especially in 2 and 4 wheeler is the increased premium they would have to pay if in an accident, so they usually compromise with the other and pay off the Traffic Inspector.
Sadly, I havenât read a new book, although there are a few books Iâm looking forward to have. People living in India and neighbors please be careful as more heat waves are expected. Till later.
Nicola Iarocci: Python `decimal.getcontext` does not work with bpython
ListenData: Transformers Agent: AI Tool That Automates Everything
We have a new AI tool in the market called Transformers Agent which is so powerful that it can automate just about any task you can think of. It can generate and edit images, video, audio, answer questions about documents, convert speech to text and do a lot of other things.
Hugging Face, a well-known name in the open-source AI world, released Transformers Agent that provides a natural language API on top of transformers. The API is designed to be easy to use. With a single line code, it provides a variety of tools for performing natural language tasks, such as question answering, image generation, video generation, text to speech, text classification, and summarization.
READ MORE »This post appeared first on ListenDataUsing Kirigami built with Qt6 without kdesrc-build
Michael Ablassmeier: updating to bookworm
Just updated to bookworm. Only thing that gave me headaches was OpenVPN refusing to accept the password/username combination specified via âauth-user-passâ option..
Mystery was solved by adding âproviders legacy defaultâ to the configuration file used.
PreviousNext: What if? Pitching for a Decoupled Layout Builder
Itâs time to transform and improve the Layout Builder UI experience. What if we could rewrite it using React? Check out our video pitch (made using React), which received the highest average rank in the Pitch-burgh contest at DrupalCon!
by lee.rowlands / 6 June 2023At PreviousNext, we enjoy getting curious, tackling challenges and finding innovative solutions for our clients and the wider Drupal community. This constant drive for the future is why weâre such prolific contributors to the Drupal project.Â
What if we used our curiosity and expertise to explore the concept of a decoupled Layout Builder?
Â
The PitchSimply put, we believe creating a better experience for the Layout Builder user interface is possible. Getting there would mean leveraging a modern Javascript framework, like React, that communicates with Drupal over JSON.
We would plan to design an API that describes the future state of how a Decoupled Layout Builder could work, dramatically enhancing the content editor experience and bringing Drupal into the modern era of web UX. It would also strengthen Drupalâs reputation with marketers.
Â
The case for an improved Layout Builder user experienceWhat if Layout Builder could move forward? Itâs currently built with Drupal technologies that haven't significantly progressed in ten years.
Page edits use Drupal's AJAX API, which requires a round trip back to the server to perform UI updates. The server updates state on the server side and then returns a series of Javascript commands to update the page state.
This round trip is inconsistent with the instant experience users expect from the modern web.Â
Â
Our solutionApplications that leverage modern Javascript frameworks perform optimistic updates. They update the UI immediately and then update state on the server in the background.
We want layout retrieval and updates to happen in real time for more dynamic editing. To achieve this, we would rebuild the Layout Builder UI using React and identify the pain points.
This would be a significant jump, similar to the change to the block-based editor in WordPress.
Rather than starting from scratch, we could leverage a lot of prior art from the WordPress community. However, we would also bring our strengths into play, retaining our uniquely Drupal focus on structured data instead of serialising to HTML.Â
Â
Proof of conceptReact is the best and most obvious option for the proof of concept. It was selected as the framework of choice for Drupal core development and has a large ecosystem. It was also successful in helping set WordPress up for the future.Â
What if itâs Drupalâs turn next?
To retain structured data, it would be necessary to provide React versions of our existing formatters and widgets and a way for developers to create their own.
This approach would require a Javascript way of declaring layouts. Again, we could take a lot of this from existing layout plugins but would require a React component for the HTML representation.
We would also need to incorporate a Javascript way of declaring blocks. Much could be derived from our existing structured content modelling. However, assuming there would be a build step where this data is used for scaffolding Javascript code is reasonable.
JSON:API could be leveraged where possible, but we envisage needing to make new JSON endpoints for data that doesn't map to entities.
Once we had achieved a non-twig way of rendering widgets, formatters, blocks and layouts, we could keep the layout state in the browser, mutate it immediately and persist to the backend in the background.
Â
Is a decoupled Layout Builder feasible?There are a number of hard problems we'll need to solve here, such as how we allow modules to ship Javascript that relies on bundling, how we ensure there's only one version of React loaded into the page, and how we allow modules to rely on other packages from npm. Solving those will be a big part of this work, and even if a React-powered Layout Builder doesn't make its way from experimental to stable, the lessons learned in the process could solve some long-standing hard problems for Drupal in the front end space.
Â
React in videoWe decided it would be a fitting way to demonstrate how powerful React is by using it to make our Pitch-burgh video submission.Â
We received the highest average rank when the video was shown during the Driesnote address at DrupalCon Pittsburgh, and look forward to the next steps for this exciting concept.Â
Huge shout out to the team who worked on creating the pitch video especially the wizard of words Fiona, frontend Guru Jack and the excellent QA and GIF selection from Kim and Tina.
Enjoy!
Ned Batchelder: Multi-syntax configuration examples
Coverage.py reads settings from a number of different files, in either INI-file or TOML syntax, with different section headings depending on the file. This could be confusing: the docs showed the syntax needed for .coveragerc, but if you were using one of the other files, you had to mentally convert from one syntax to another.
To make it easier, I updated the documentation to show all the syntax possibilities when showing examples of configuration files.
The result looks like this: a three-tabbed code box. The tabs have the names of configuration files. Selecting a tab shows the syntax you need for that particular file:
Originally I wanted to write the settings just once, and use cog to run Python code to convert from INI syntax to TOML.
If you haven’t seen cog before, it lets you insert small chunks of Python into static files. The Python code is executed to generate more static content that appears alongside the Python code. It’s a simple tool that works well when you have a mostly static file, but you want part of it to be computed.
But I sensed that converting between syntaxes be difficult, especially since some of my examples (as the ones above) have comments in them.
So I went with a simpler approach: the Python snippets in the doc files have both INI and TOML chunks. The INI chunk is lightly massaged to make two of the tabs, since they only differ in the section names. To ensure the two input chunks are in sync, the code reads the configuration examples, and checks that the INI and TOML chunks create the same settings values.
This guarantees that the different syntaxes are all valid, both as generic INI or TOML, but also as coverage.py settings. And it guarantees that the two chunks show the same settings, differing only in syntax.
It’s a little bulky in the resulting .rst files, but it provides the reader with the information they need, and it keeps me from making mistakes.
If you want to see the code, the cog code is in cog_helpers.py, and a small example of how it’s used in the documentation is in context.rst.